★ 什麼是資源?
開發過程中與業務無關的服務、類的實例或者變量的值。比如:Apusic J2EE應用服務器管理的JDBC服務是資源,用戶開發的EJB、WebService是資源、用戶定義的配置文件也是資源。
★ 為什麼要資源注入?
大多數企業級Java應用程序都使用了諸如DataSources,EJBs或WebService的外在的資源和服務,在J2EE 1.4中,用戶必須在部署描述符中明確聲明所依賴的資源或者使用JNDI的lookup方法去獲得資源的引用。
最初目的是為了減少應用與資源的依賴度,具體可以參考IoC(控制反轉)和DI(依賴注入),但現在作者認為優點很多:1. 減少應用與資源的依賴度,便於應用的後期組裝。例如:將數據庫連接池在後期組裝時作為資源注入到系統中,這樣使應用在開發過程中不會與資源綁定。
2. 簡化應用的復雜度,使程序員開發中更多關注業務。例如:通過標注將資源在變量定義的時候注入進去,開發人員直接可以使用變量,而無須再通過代碼獲得。
3. 規范應用的開發過程,提升應用後期運行的穩定性。例如:通過注入的方式使用資源,而無須在開發期管理資源的生命周期以及創建與銷毀,避免出現重復創建或者內存洩漏。
★ 哪些資源可以注入?
數據源、JMS目的地、環境變量、EJB、WebService、上下文資源、Managed Bean、Spring Bean、LocalString
★ 如何注入和使用資源?
// Apusic系統日志,采用的是JDK 1.4的日志系統
@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
messages.get("WindowBean.email.required");
// 配置文件注入上下文資源
在faces-config.XML中在需要注入的bean中加入managed-property屬性和值
com.apusic.examples.crud.second.bean.WindowBean
在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