Spring高階用法--自定義業務物件元件化
若干年前在使用SpringMVC的時候,發現springMVC可以把HttpSession,HttpRequest元件化注入:
@Autowired HttpSession session; @Autowired HttpRequest httpRequest;
於是花了30分鐘追蹤了相關的原始碼徹底摸清其原理,並且決定將使用者(User/Principle)也元件化(儘管當時工作處於極其忙碌的狀態,也忍不住去研究)。
**方法如下:** 1. 定義IPrincipal(IUser)介面 interface IPrincipal extends Serializable { IPrincipal get() } 2. 實現PrincipalObjectFactory class PrincipalObjectFactory implements ObjectFactory<IPrincipal>, Serializable { @Override IPrincipal getObject() { def requestAttr = RequestContextHolder.currentRequestAttributes() def request = requestAttr.getRequest() def p = new PrincipalHelper(request).get() new IPrincipal() { @Override IPrincipal get() { p } } } } 3. 在spring的上下文中註冊依賴處理器 beanFactory.registerResolvableDependency(IPrincipal, new PrincipalObjectFactory())
只需要以上步驟,即可使用@Autowired在業務程式碼中注入IPrincipal(IUser),並且保證其執行緒安全。
**原理:** 閱讀spring原始碼會發現,spring在注入介面時如果發現沒有介面的實現類,就會從ResolvableDependency中尋找相關的依賴解決器。 如果註冊了相關的依賴解決器,會給此介面注入一個代理類,這個代理類的target就是ObjectFactory#getObject,在這裡就可實現你的IPrincipal(IUser)獲取了。 **總結** 1 使用這個方式將IPrincipal(IUser)元件化,而不是通過工具類的方式去獲取。 **這樣的方式充分體現了spring的依賴注入的思想,並且系統耦合性也降低不少。** 2 **即使在spring上下文中注入ObjectFactory,spring並不會自動註冊,需要自動註冊。**