什麼是依賴呢。
簡單的說,就是A組件需要調用B組件,B組件需要調用C組件,C組件需要調用D組件…..這種調用稱為:依賴。
在最早的應用程式中,依賴關係時通過new關鍵字來實現的。A組件依賴B組件,就是在A組件中顯示的new一個B組件。缺點:
1、寫入程式碼,耦合性強,難以維護。A組件只需要B組件中的方法,不必關心B組件的建立問題。
2、頻繁的建立對象,導致系統開銷增大。
上面的這種缺點,直接催生了‘原廠模式’。
在原廠模式中,A組件依賴B組件時,A組件不再負責建立B組件,B組件的建立由工廠完成,A組件只需要跟工廠要就夠了。
從代碼角度來看,可以把JNDI尋找看做是典型的原廠模式。
把Context當做是工廠,jndi當做是被生產的產品。
Context ctx=new InitialContext();
Xxx xx=(Xxx)ctx.lookup(jndi);
而實際上,JNDI並不是原廠模式。那麼到底是誰生產的這些產品呢。正確答案是:我們通常用XML的方式來設定物件,而真正建立這些對象的是一個用伺服器、EJB容器這類工廠,只不過他們都是功能異常強大的工廠。
當應用伺服器、EJB容器把各種對象(如:資料來源,JMS訊息目的、EJB執行個體)建立出來之後,接下來就是給這些對象起個可以全域訪問的名字供外界訪問。這個過程被稱作是:JNDI綁定。
而通過JNDI尋找應用伺服器,EJB容器中時,就相當於用戶端向工廠要他們所相依元件的過程。
再後來,Spring架構提出依賴注入的概念。
當A組件依賴B組件時,開發人員通過XML檔案或者Annotation進行配置,而由容器來負責執行個體化B組件,並將B組件注入到A組件中,這就是所謂的依賴注入。
很明顯,依賴注入是建立在原廠模式的基礎上又向前走了一步。使用依賴注入後,當A組件依賴B組件時,A組件不再需要向工廠要B組件,而是由容器主動將B組件注入到A組件中。
依賴注入比JNDI尋找更先進,更有利於代碼解耦。
關於依賴注入,本文主要從以下兩方面講解:資源依賴、EJB依賴
1.資源依賴 @Resource@Resources
如:A組件依賴於某個資料來源資源,某個JMS訊息目的等
2.EJB依賴 @EJB@EJBs
如:A組件依賴於某個EJB。
( 一)EJB注入
EJB注入主要靠位於javax.ejb包下的@EJB@EJBs兩個Annotation來提供。
@EJB既可以用於修飾Bean實作類別的成員變數,也可以用於修飾Bean類setter方法。EJB容器的依賴注入會自動將對應的EJB注入該Field或setter方法中。
使用@EJB時,可以指定如下屬性:
beanInterface:該屬性指定被注入EJB所實現的介面。該屬性通常用於區分所引用的Bean是遠程調用Bean,還是本地Bean
name:用於指定被注入的Bean在JNDI ENC中的註冊項名稱,該名稱在不同應用伺服器中可能存在差異。
beanName:該屬性指定被注入EJB的名稱,用起來比較方便。其值與被注入Bean中@Stateless.name @Stateful.name 或ejb-jar.xml中<ejb-name…>元素所指定的值相等。
mappedName:指定被注入EJB的JNDI名,但由於全域JNDI名與應用伺服器廠商有關係,因此設定該屬性可能降低應用的可移植性。
本例將介紹:本地調用的EJB注入遠程調用的EJB中,從而間接的讓本地EJB也可以對外提供服務。
本地調用EJB,業務介面 [java] view plain copy @Local Public interface Hello{ Public String hello(String name); }
本地調用EJB,實作類別 [java] view plain copy @Stateless(name="Hello") Public class HelloBean implements Hello{ Public String hello(String name){ Return name+",現在時間:"+new java.util.Date(); } }
新的EJB,業務介面 [java] view plain copy @Remote Public interface CallHello{ String callHello(String name); }
接下來定義新的EJB,用於調用上面的Hello EJB。(此時不需要JNDI尋找,而是通過依賴注入的方式)
新的EJB,實作類別 [java] view plain copy