★ 什么是資源?
開發(fā)過程中與業(yè)務無關的服務、類的實例或者變量的值。比如:Apusic J2EE應用服務器管理的JDBC服務是資源,用戶開發(fā)的EJB、WebService是資源、用戶定義的配置文件也是資源。
★ 為什么要資源注入?
大多數企業(yè)級java應用程序都使用了諸如DataSources,EJBs或WebService的外在的資源和服務,在J2EE 1.4中,用戶必須在部署描述符中明確聲明所依賴的資源或者使用JNDI的lookup方法去獲得資源的引用。
最初目的是為了減少應用與資源的依賴度,具體可以參考IoC(控制反轉)和DI(依賴注入),但現在作者認為優(yōu)點很多:
1. 減少應用與資源的依賴度,便于應用的后期組裝。例如:將數據庫連接池在后期組裝時作為資源注入到系統(tǒng)中,這樣使應用在開發(fā)過程中不會與資源綁定。
2. 簡化應用的復雜度,使程序員開發(fā)中更多關注業(yè)務。例如:通過標注將資源在變量定義的時候注入進去,開發(fā)人員直接可以使用變量,而無須再通過代碼獲得。
3. 規(guī)范應用的開發(fā)過程,提升應用后期運行的穩(wěn)定性。例如:通過注入的方式使用資源,而無須在開發(fā)期管理資源的生命周期以及創(chuàng)建與銷毀,避免出現重復創(chuàng)建或者內存泄漏。
★ 哪些資源可以注入?
數據源、JMS目的地、環(huán)境變量、EJB、WebService、上下文資源、Managed Bean、Spring Bean、LocalString
★ 如何注入和使用資源?
?// Apusic系統(tǒng)日志,采用的是JDK 1.4的日志系統(tǒng)
?@Inject
?private java.util.logging.Logger logger;
?public void IndexBean() {
??logger.info("初始化IndexBean!");
?}
??? // JavaServer Faces的相關資源
?// JSF的FacesContext
?@Inject
?private javax.faces.context.FacesContext fContext;
??? // 獲取應用的HttpRequest
??? HttpServletRequest request=(HttpServletRequest)fContext.getCurrentInstance().getExternalContext().getRequest();
??? // 獲取應用的HttpResponse
??? HttpServletResponse request=(HttpServletResponse)fContext.getCurrentInstance().getExternalContext().getResponse();
??? // 獲取應用的HttpSession
??? HttpSession session=(HttpSession) fContext.getCurrentInstance().getExternalContext().getSession(true);
??? // JSF的服務器實例
?@Inject
?private javax.faces.application.Application app;
?// JSF的導航句柄
?@Inject
?private javax.faces.application.NavigationHandler nHandler;
?// JSF的EL表達式工廠實例
?@Inject
?private javax.el.ExpressionFactory expFactory;
?// JSF的事件廣播者實例
?@Inject
?private org.operamasks.faces.event.EventBroadcaster event;
?// 相同生命周期的ManagedBean,參考CRUD例子
?@Inject
?private IndexBean indexBean;
?// JNDI資源注入
?// 數據庫連接池資源注入
?@Resource(mappedName = "jdbc/CRUD")
?private javax.sql.DataSource CRUD;
? ?Connection con = CRUD.getConnection();
?// 消息工廠資源注入
?@Resource(mappedName="jms/ConnectionFactory")
?private javax.jms.ConnectionFactory connFactory;
?// 消息主題資源注入
?@Resource(mappedName="testTopic")
?private javax.jms.Topic topic;
?// 消息隊列資源注入
?@Resource(mappedName="testQueue")
?private javax.jms.Queue queue;
?// 事務服務資源注入,一個線程只提供一個事務服務,因此不需要提供名稱直接可以注入
?@Resource
?private javax.transaction.UserTransaction tx;
?
?// EJB資源注入
?@EJB(name="com.apusic.examples.crud.second.service.PersonService")
?IPersonService personService;
?
?// 資源文件的注入,注意:只能注入前綴為LocalStrings的文件組
?@LocalString
?private Map<String, String> messages;
?messages.get("WindowBean.email.required");
?
??? // 配置文件注入上下文資源
??? 在faces-config.xml中在需要注入的bean中加入managed-property屬性和值
?<managed-bean>
??<managed-bean-name>windowBean</managed-bean-name>
??<managed-bean-class>
???com.apusic.examples.crud.second.bean.WindowBean
??</managed-bean-class>
??<managed-bean-scope>session</managed-bean-scope>
??<managed-property>
???<property-name>injectName</property-name>
???<property-class>java.lang.String</property-class>
???<value>Operamasks</value>
??</managed-property>
?</managed-bean>
?在WindowBean.java中直接定義
?private String injectName;
?public void setInjectName(String injectName) { // 通過這個函數提供資源注入
??this.injectName = injectName;
?}
★ 參考資料
http://www.matrix.org.cn/resource/article/2006-04-05/Dependency+Injection_44321.html
★ 備注
本文現在只介紹了基礎資源注入知識,隨著作者本人對資源注入的理解,將會繼續(xù)補充與完善。