Spring依賴注入技術的發展

回顧Spring框架的歷史,您會發現實現依賴注入的方式在每個發行版中都在增加。

如果您使用該框架已經超過一個月,那么在這篇回顧性文章中可能不會發現任何有趣的東西。 除了Scala中的最后一個示例,沒有其他希望,這種語言在Spring中意外地很好用。

首先是XML [ 全文 ]:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd "><bean id="foo" class="com.blogspot.nurkiewicz.Foo"><property name="bar" ref="bar"/><property name="jdbcOperations" ref="jdbcTemplate"/></bean><bean id="bar" class="com.blogspot.nurkiewicz.Bar" init-method="init"/><bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"><property name="driverClassName" value="org.h2.Driver"/><property name="url" value="jdbc:h2:mem:"/><property name="username" value="sa"/></bean><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><constructor-arg ref="dataSource"/></bean>
</beans>

這個簡單的應用程序僅獲取H2數據庫服務器時間并以完整格式打印它:

public class Foo {private Bar bar;private JdbcOperations jdbcOperations;public String serverTime() {return bar.format(jdbcOperations.queryForObject("SELECT now()", Date.class));}public void setBar(Bar bar) {this.bar = bar;}public void setJdbcOperations(JdbcOperations jdbcOperations) {this.jdbcOperations = jdbcOperations;}
}
public class Bar {private FastDateFormat dateFormat;public void init() {dateFormat = FastDateFormat.getDateTimeInstance(FULL, FULL);}public String format(Date date) {return dateFormat.format(date);}
}

這段代碼有些令人不安。 首先,令人驚訝的是有很多XML。 與類似的EJB 2.1應用程序相比,它仍然要少一些(此代碼在2006年的Spring 1.2.6上進行了微小的更改 ),但是感覺很不對。 公共設置者更加令人不安–為什么我們被迫在任何時候任何人都公開覆蓋對象依賴的能力? 順便說一下,我從來沒有真正理解過為什么為什么在使用tag時Spring不允許直接將依賴項注入到私有字段中,因為這樣做可能……

批注 [ 全文 ]

Java 5和Spring 2.5帶來了對注釋驅動的依賴注入的支持:

<context:annotation-config/><!-- or even: --><context:component-scan base-package="com.blogspot.nurkiewicz"/>

從第一行開始,您不再需要在XML中定義<property>標簽,只需定義<bean>。 該框架將獲取標準的@Resource注釋。 將其替換為第二行,甚至根本不需要在XML中指定bean:

@Service
public class Foo {@Resourceprivate Bar bar;@Resourceprivate JdbcOperations jdbcOperations;public String serverTime() {return bar.format(jdbcOperations.queryForObject("SELECT now()", Date.class));}
}
@Service
public class Bar {private FastDateFormat dateFormat;@PostConstructpublic void init() {dateFormat = FastDateFormat.getDateTimeInstance(FULL, FULL);}public String format(Date date) {return dateFormat.format(date);}
}

當然,您不會留下深刻的印象! 尼爾·諾維(Nihil Novi) 。 另外,我們仍然必須使用XML,因為我們無法控制第三方類(例如數據源和JdbcTemplate ),因此無法對其進行注釋。 但是Spring 3.0引入了:

@Configuration [ 完整源代碼 ]

我已經在探索@ Configuration / @ Bean支持,因此這次請重點關注如何啟動應用程序上下文。 您看到對XML文件的任何引用嗎? applicationContext.xml描述符完全消失了:

@ComponentScan("com.blogspot.nurkiewicz")
public class Bootstrap {private static final Logger log = LoggerFactory.getLogger(Bootstrap.class);@Beanpublic DataSource dataSource() {final BasicDataSource dataSource = new BasicDataSource();dataSource.setDriverClassName("org.h2.Driver");dataSource.setUrl("jdbc:h2:mem:");dataSource.setUsername("sa");return dataSource;}@Beanpublic JdbcTemplate jdbcTemplate() {return new JdbcTemplate(dataSource());}public static void main(String[] args) {final AbstractApplicationContext applicationContext = new AnnotationConfigApplicationContext(Bootstrap.class);final Foo foo = applicationContext.getBean(Foo.class);log.info(foo.serverTime());applicationContext.close();}
}

如您所見,Spring從使用大量XML到不使用XML的框架走了很長的路。 但最令人興奮的部分是您可以使用喜歡的任何樣式,甚至可以將它們混合使用。 您可以使用舊版Spring應用程序并開始使用批注或切換到XML,因為上帝知道這里或那里的原因。

我沒有提到的一種技術是構造函數注入。 它有一些很大的好處(請參閱使用構造函數進行依賴注入? ),例如將依賴關系標記為最終的并禁止創建未初始化對象的能力:

@Service
public class Foo {private final Bar bar;private final JdbcOperations jdbcOperations;@Autowiredpublic Foo(Bar bar, JdbcOperations jdbcOperations) {this.bar = bar;this.jdbcOperations = jdbcOperations;}//...}

我希望構造函數注入,但是再次感到有點失望。 每個對象依賴項都需要(a)構造函數參數,(b)最終字段和(c)構造函數中的賦值操作。 我們最后得到十行代碼,這些行什么都不做。 這個健談的代碼克服了所有優點。 當然,任何對象都不應具有超過(在這里輸入您的數字)的依賴關系-借助構造函數注入,您會立即看到該對象具有太多的依賴關系-但我仍然發現此代碼引入了太多的儀式。

用Scala注入Spring構造函數 [ 完整源代碼 ]

Scala的一個功能完全適合Spring框架:默認情況下,任何Scala對象的每個參數都會創建與該參數相同的最終字段。 對我們而言,這意味著什么? 看看翻譯成Scala的Foo類:

@Service
class Foo @Autowired() (bar: Bar, jdbcOperations: JdbcOperations) {def serverTime() = bar.format(jdbcOperations.queryForObject("SELECT now()", classOf[Date]))}

認真嗎 但是……怎么了? 在這里深入了解Scala的優勢之前,請看一下Java反編譯器生成的等效Java代碼:

@Service
public class Foo implements ScalaObject
{private final Bar bar;private final JdbcOperations jdbcOperations;@Autowiredpublic Foo(Bar bar, JdbcOperations jdbcOperations){this.bar = bar;this.jdbcOperations = jdbcOperations;}public String serverTime(){return this.bar.format(this.jdbcOperations.queryForObject("SELECT now()", Date.class));}}

與我們用Java編寫的代碼幾乎完全相同。 擁有所有優勢:依賴最終將使我們的服務真正不變和無狀態; 依賴是私有的,不會暴露給外界; 實際上,不需要額外的代碼來管理依賴項:只需添加構造函數參數,Scala就會處理其余的工作。

總結一下–您擁有廣泛的可能性。 從XML到Java代碼再到Scala。 最后一種方法實際上很誘人,因為它使您擺脫了所有樣板,并使您可以專注于業務功能。 完整的源代碼可在我的GitHub存儲庫中找到,每個步驟都帶有標簽,因此您可以比較和選擇最喜歡的方法。

參考資料: NoBlogDefFound的JCG合作伙伴Tomek Nurkiewicz提供的Spring依賴注入技術的 發展

編碼愉快! 不要忘記分享!

相關文章:

  • Java最佳實踐系列
  • 正確記錄應用程序的10個技巧
  • 每個程序員都應該知道的事情
  • 生存在狂野西部開發過程中的9條提示
  • 軟件設計法則
  • Java Fork / Join進行并行編程

翻譯自: https://www.javacodegeeks.com/2011/09/evolution-of-spring-dependency.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/374674.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/374674.shtml
英文地址,請注明出處:http://en.pswp.cn/news/374674.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

JS encode decode

網上查到的全都是escape&#xff0c;和需要的編碼不是一回事&#xff0c;好不容易找到的結果 保存下來以備以后使用js對文字進行編碼涉及3個函數&#xff1a;escape,encodeURI,encodeURIComponent&#xff0c;相應3個解碼函數&#xff1a;unescape,decodeURI,decodeURIComponen…

流媒體服務器 筆記

1.sip服務器回SBC Port Unreachable 說明轉碼器接收RTCP的端口沒有打開 轉載于:https://www.cnblogs.com/luoyinjie/p/7219359.html

力扣151. 翻轉字符串里的單詞

給你一個字符串 s &#xff0c;逐個翻轉字符串中的所有 單詞 。 單詞 是由非空格字符組成的字符串。s 中使用至少一個空格將字符串中的 單詞 分隔開。 請你返回一個翻轉 s 中單詞順序并用單個空格相連的字符串。 沒思路&#xff0c;看到的官方給的&#xff0c;簡潔明了&…

Spring 3 HornetQ 2.1集成教程

通過Spring框架使用JBoss的新超高性能消息傳遞系統。 HornetQ是一個開放源代碼項目&#xff0c;用于構建多協議&#xff0c;可嵌入&#xff0c;非常高性能的集群異步消息傳遞系統。 它是用Java編寫的&#xff0c;并且可以在具有Java 5或更高版本運行時的任何平臺上運行。 Horn…

B/S和C/S架構圖解

軟件&#xff1a;B/S和C/S兩種架構模式。接下來用三張圖片解釋&#xff0c;什么是B/S什么是C/S。 圖片一&#xff1a;軟件架構模式 圖片二&#xff1a;C/S結構模式 圖片三&#xff1a;B/S結構模式 相信圖解勝過冗長文字的解釋&#xff0c;什么是B/S什么是C/S一目了然。 轉載于:…

557. 反轉字符串中的單詞 III

給定一個字符串&#xff0c;你需要反轉字符串中每個單詞的字符順序&#xff0c;同時仍保留空格和單詞的初始順序。 class Solution {public String reverseWords(String s) {StringBuffer res new StringBuffer();int length s.length();int i 0;while(i < length){int …

休眠陷阱

我已經使用Hibernate已有一段時間了&#xff0c;當我一段時間不使用Hibernate項目時&#xff0c;發現自己犯的錯誤與上次相同。 因此&#xff0c;這是我的監視清單&#xff0c;希望對其他人也有用。 實現hashCode和equals 一般而言&#xff0c;應該始終實現這些方法&#xff…

HDU 5371 Hotaru's problem (Manacher,回文串)

題意&#xff1a;給一個序列&#xff0c;找出1個連續子序列&#xff0c;將其平分成前&#xff0c;中&#xff0c;后等長的3段子序列&#xff0c;要求【前】和【中】是回文&#xff0c;【中】和【后】是回文。求3段最長為多少&#xff1f;由于平分的關系&#xff0c;所以答案應該…

bash 與 dash

Ubuntu 的 bash和dash的區別 什么是bash &#xff1f; Bash(GNU Bourne-Again Shell)是許多Linux平臺的內定Shell&#xff0c;事實上&#xff0c;還有許多傳統UNIX上用的Shell&#xff0c;像tcsh、csh、ash、bsh、ksh等 等&#xff0c;Shell Script大致都類同&#xff0c;當您學…

350. 兩個數組的交集 II

給你兩個整數數組 nums1 和 nums2 &#xff0c;請你以數組形式返回兩數組的交集。返回結果中每個元素出現的次數&#xff0c;應與元素在兩個數組中都出現的次數一致&#xff08;如果出現次數不一致&#xff0c;則考慮取較小值&#xff09;。可以不考慮輸出結果的順序。 來源&a…

Eclipse:如何附加Java源代碼

在Eclipse中&#xff0c;當您按Ctrl按鈕并單擊任何類名稱時&#xff0c;IDE會將您帶到該類的源文件。 這是項目中具有的類的正常行為。 但是&#xff0c;如果您也希望Java核心類具有相同的行為&#xff0c;則可以通過將Java源代碼附加到Eclipse IDE來實現。 一旦附加了源代碼&a…

【樹狀數組】

問題的提出&#xff1a;是否可以用線性數據結構的方法解決動態統計子樹權和的問題呢&#xff1f; 有的&#xff0c;樹狀數組。 假設當前數組為a[]&#xff0c;元素個數為n。 1. 子區間的權和數組為sum&#xff0c;那么數組a[]中 i 到 j這段區間的數組元素和為sum[i,j] a[k]的累…

2013VS快捷鍵

VS2013常用快捷鍵&#xff1a; 1.回到上一個光標位置/前進到下一個光標位置 1&#xff09;回到上一個光標位置&#xff1a;使用組合鍵“Ctrl -”&#xff1b; 2&#xff09;前進到下一個光標位置&#xff1a;“Ctrl Shift - ”。 2.復制/剪切/刪除整行代碼 1&#xff09;如果…

GWT,GWT-Ext(SmartGWT),GXT(Ext GWT)常見任務

我在我們的JCG合作伙伴之一UI-Programming博客上瀏覽了一些舊文章&#xff0c;并注意到有很多簡短的文章&#xff0c;介紹了如何使用GWT&#xff0c;GWT-Ext&#xff08;SmartGWT&#xff09;和GXT&#xff08;Ext GWT&#xff09;執行一些常見任務。 &#xff09;。 我相信它們…

h.264 去塊濾波

塊效應及其產生原因 我們在觀看視頻的時候&#xff0c;在運動劇烈的場景常能觀察到圖像出現小方塊&#xff0c;小方塊在邊界處呈現不連續的效果&#xff08;如下圖&#xff09;&#xff0c;這種現象被稱為塊效應&#xff08;blocking artifact&#xff09;。 首先我們需要搞清楚…

android開發的知識點(一)

1.android中背景圖的設置&#xff1a; 將背景圖放入到項目中的res/drawable-hdpi或res/drawable-mdpi或res/drawable-xhdpi或res/drawable-xxhdpi等任一文件夾下。然后在layout的xml文件夾下使用android:background"drawable/背景圖名"&#xff0c;其中背景圖必須是p…

566. 重塑矩陣

在 MATLAB 中&#xff0c;有一個非常有用的函數 reshape &#xff0c;它可以將一個 m x n 矩陣重塑為另一個大小不同&#xff08;r x c&#xff09;的新矩陣&#xff0c;但保留其原始數據。 給你一個由二維數組 mat 表示的 m x n 矩陣&#xff0c;以及兩個正整數 r 和 c &…

RabbitMQ播放模塊! 構架

RabbitMQ提供了具有可預測且一致的吞吐量和延遲的高可用性&#xff0c;可伸縮和便攜式消息系統。 RabbitMQ是AMQP &#xff08;業務消息傳遞的開放標準&#xff09;的領先實現 &#xff0c;并且通過適配器支持XMPP&#xff0c;SMTP&#xff0c;STOMP和HTTP來進行輕量級Web消息傳…

Cyclic Nacklace - HDU 3746(next求循環節)

題目大意&#xff1a;給你一些串&#xff0c;問如果想讓這個串里面的循環節至少循環兩次&#xff0c;需要添加幾個字符&#xff08;只能在最前面或者最后面添加&#xff09;。比如ababc 需要添加5個就是添加ababc。 分析&#xff1a;其實字符串的長度len-next[len] 最小循環節…

Xuggler開發教程

大家好&#xff0c; 在這篇文章中&#xff0c;我想介紹JavaCodeGeeks上的一些很酷的新教程。 他們將討論與Xuggler &#xff0c; FFmpeg和Wowza進行媒體&#xff08;音頻/視頻&#xff09;操縱的方式。 我將在這篇文章中跟蹤所有相關的教程。 您可以通過查看Pat較早的關于使用…