若干年前在使用SpringMVC的時候,發現springMVC能夠把HttpSession,HttpRequest組件化注入:spring
@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),而且保證其線程安全。session
**原理:** 閱讀spring源碼會發現,spring在注入接口時若是發現沒有接口的實現類,就會從ResolvableDependency中尋找相關的依賴解決器。 若是註冊了相關的依賴解決器,會給此接口注入一個代理類,這個代理類的target就是ObjectFactory#getObject,在這裏就可實現你的IPrincipal(IUser)獲取了。 **總結** 1 使用這個方式將IPrincipal(IUser)組件化,而不是經過工具類的方式去獲取。 **這樣的方式充分體現了spring的依賴注入的思想,而且系統耦合性也下降很多。** 2 **即便在spring上下文中注入ObjectFactory,spring並不會自動註冊,須要手動註冊。**
Created by suyaqiang (sueeing@126.com) on 2019/1/20.ide