歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Spring源碼解析 - BeanFactory接口體系解讀

Spring源碼解析 - BeanFactory接口體系解讀

日期:2017/3/1 9:18:10   编辑:Linux編程

不知道為什麼看著Spring的源碼,感觸最深的是Spring對概念的抽象,所以我就先學接口了,BeanFactory是Spring IOC實現的基礎,這邊定義了一系列的接口,我們通過這些接口的學習,可以大致了解BeanFactory體系各接口如何分工合作。

為學習具體實現打下基礎.畢竟這邊邏輯復雜,涉及的概念很多.

BeanFactory 是Spring bean容器的根接口.提供獲取bean,是否包含bean,是否單例與原型,獲取bean類型,bean 別名的api.

-- AutowireCapableBeanFactory 添加集成其他框架功能.如果集成WebWork則可以使用Spring對Actions等進行管理.

-- HierarchicalBeanFactory 提供父容器的訪問功能

-- -- ConfigurableBeanFactory 如名,提供factory的配置功能,眼花缭亂好多api

-- -- -- ConfigurableListableBeanFactory 集大成者,提供解析,修改bean定義,並與初始化單例.

-- ListableBeanFactory 提供容器內bean實例的枚舉功能.這邊不會考慮父容器內的實例.

看到這邊,我們是不是想起了設計模式原則裡的接口隔離原則

Interface Segregation Principle(ISP):客戶端不應該依賴它不需要的接口;類間的依賴關系應該建立在最小的接口上

這邊清晰地定義了如下的體系:

  根接口BeanFactory(基礎容器)

  第二層: 第三方集成,繼承體系,遍歷bean

  第三層: 配置功能

  第四層: 配置+迭代

接下來具體分析下各個接口吧(順便做目錄):

1. BeanFactory

2. AutowireCapableBeanFactory

3. HierarchicalBeanFactory

4. ListableBeanFactory

5. ConfigurableBeanFactory

6. ConfigableListableBeanFactory

1. BeanFactory

BeanFactory是Spring bean容器的根接口.

每個bean都是通過string類型bean name進行標識.這邊提供了設計模式單例,原型的替代實現.

如果bean name配置為單例,應用內只會獲取到一個實例.如果配置為原型,那麼可以實例化好後填充屬性(基於用戶的配置).

BeanFactory作為應用集中配置管理的地方,極大簡便應用開發,這樣開發人員可以集中與業務.

BeanFactory需要管理bean的生命周期,比如初始化時需要按順序實現如下接口:

  1. BeanNameAware's {@code setBeanName}
  2. BeanClassLoaderAware's {@code setBeanClassLoader}
  3. BeanFactoryAware's {@code setBeanFactory}
  4. ResourceLoaderAware's {@code setResourceLoader}僅對application context有效
  5. ApplicationEventPublisherAware's {@code setApplicationEventPublisher}僅對application context有效
  6. MessageSourceAware's {@code setMessageSource}僅對application context有效
  7. ApplicationContextAware's {@code setApplicationContext}僅對application context有效
  8. ServletContextAware's {@code setServletContext}僅對application context有效
  9. {@code postProcessBeforeInitialization} methods of BeanPostProcessors
  10. InitializingBean's {@code afterPropertiesSet}
  11. a custom init-method definition xml中配置的init-method
  12. {@code postProcessAfterInitialization} methods of BeanPostProcessors

還有關閉容器的接口:

  1. DisposableBean's {@code destroy}
  2. a custom destroy-method definition xml配置中的destroy-method

接口裡定義了一個變量String FACTORY_BEAN_PREFIX = "&";

  這是用來區分是獲取FactoryBean還是FactoryBean的createBean創建的實例.如果&開始則獲取FactoryBean;否則獲取createBean創建的實例.

我們來看下定義的方法:

  a, 獲取bean,這邊可以實現單例,原型

    Object getBean(String name) throws BeansException; 可以用別名查找哦

    <T> T getBean(String name, Class<T> requiredType) throws BeansException;

    <T> T getBean(Class<T> requiredType) throws BeansException; 這邊的類型可以是接口或者子類,但不能是null

    Object getBean(String name, Object... args) throws BeansException;

  b, 判斷是否包含bean.陷阱出現:這邊不管類是否抽象類,懶加載,是否在容器范圍內,只要符合都返回true,所以這邊true,不一定能從getBean獲取實例

    boolean containsBean(String name);

  c, 單例,原型,bean類型的判斷

    boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

    boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

    boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException;

  d, 獲取bean 的類型,別名

    Class<?> getType(String name) throws NoSuchBeanDefinitionException;

    String[] getAliases(String name);

2. AutowireCapableBeanFactory

在BeanFactory基礎上實現對已存在實例的管理.

可以使用這個接口集成其它框架,捆綁並填充並不由Spring管理生命周期並已存在的實例.像集成WebWork的Actions 和Tapestry Page就很實用.

一般應用開發者不會使用這個接口,所以像ApplicationContext這樣的外觀實現類不會實現這個接口,如果真手癢癢可以通過ApplicationContext的getAutowireCapableBeanFactory接口獲取.

這邊定義了5種自動裝配策略:不注入AUTOWIRE_NO,使用bean name策略裝配AUTOWIRE_BY_NAME,使用類型裝配策略AUTOWIRE_BY_TYPE,使用構造器裝配策略AUTOWIRE_CONSTRUCTOR,自動裝配策略AUTOWIRE_AUTODETECT

  這邊的自動策略是先嘗試構造器,然後才是byType.這邊應該是跟xml配置文件中的裝配策略對應.

繼續看定義的api:

  a, 創建和填充外部bean實例的典型方法

    <T> T createBean(Class<T> beanClass) throws BeansException;

    void autowireBean(Object existingBean) throws BeansException; // 使用autowireBeanProperties裝配屬性

    Object configureBean(Object existingBean, String beanName) throws BeansException; // 自動裝配屬性,填充屬性值,使用諸如setBeanName,setBeanFactory這樣的工廠回調填充屬性,最好還要調用post processor

    Object resolveDependency(DependencyDescriptor descriptor, String beanName) throws BeansException;

  b, 在bean的生命周期進行細粒度控制的專門方法

    Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException; // 會執行bean完整的初始化,包括BeanPostProcessors和initializeBean

    Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;

    void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck) throws BeansException;

    void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException;

    Object initializeBean(Object existingBean, String beanName) throws BeansException;

    Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException;

    Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException;

    Object resolveDependency(DependencyDescriptor descriptor, String beanName, Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException;

--------------------------------------分割線 --------------------------------------

Spring中如何配置Hibernate事務 http://www.linuxidc.com/Linux/2013-12/93681.htm

Struts2整合Spring方法及原理 http://www.linuxidc.com/Linux/2013-12/93692.htm

基於 Spring 設計並實現 RESTful Web Services http://www.linuxidc.com/Linux/2013-10/91974.htm

Spring-3.2.4 + Quartz-2.2.0集成實例 http://www.linuxidc.com/Linux/2013-10/91524.htm

使用 Spring 進行單元測試 http://www.linuxidc.com/Linux/2013-09/89913.htm

運用Spring注解實現Netty服務器端UDP應用程序 http://www.linuxidc.com/Linux/2013-09/89780.htm

Spring 3.x 企業應用開發實戰 PDF完整高清掃描版+源代碼 http://www.linuxidc.com/Linux/2013-10/91357.htm

--------------------------------------分割線 --------------------------------------

3. HierarchicalBeanFactory

提供父容器的訪問功能.至於父容器的設置,需要找ConfigurableBeanFactory的setParentBeanFactory(接口把設置跟獲取給拆開了!).

這邊可說的不多,直接上api:

  a, 獲取父容器 bean factory

    BeanFactory getParentBeanFactory();

  b, 判斷當前容器是否保護bean

    boolean containsLocalBean(String name);

更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2016-03/129118p2.htm

Copyright © Linux教程網 All Rights Reserved