Spring高階用法--自定義業務對象組件化

若干年前在使用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

相關文章
相關標籤/搜索