1. 程式人生 > >spring beans原始碼解讀之 ioc容器之始祖--DefaultListableBeanFactory

spring beans原始碼解讀之 ioc容器之始祖--DefaultListableBeanFactory

spring Ioc容器的實現,從根源上是beanfactory,但真正可以作為一個可以獨立使用的ioc容器還是DefaultListableBeanFactory,因此可以這麼說,
DefaultListableBeanFactory 是整個spring ioc的始祖,研究透它的前生今世對我們理解spring ioc的概念有著重要的作用。

1. DefaultListableBeanFactory的作用:

預設實現了ListableBeanFactory和BeanDefinitionRegistry介面,基於bean definition物件,是一個成熟的bean factroy。

最典型的應用是:在訪問bean前,先註冊所有的definition(可能從bean definition配置檔案中)。使用預先建立的bean定義元資料物件,從本地的bean definition表中查詢bean definition因而將不會花費太多成本。

DefaultListableBeanFactory既可以作為一個單獨的beanFactory,也可以作為自定義beanFactory的父類。

注意:特定格式bean definition的解析器可以自己實現,也可以使用原有的解析器,如:

PropertiesBeanDefinitionReader和XmLBeanDefinitionReader。

2. DefaultListableBeanFactory的繼承關係

       (圖片來源:http://www.myexception.cn/software-architecture-design/925888.html)

3. 好了,開始進入DefaultListableBeanFactory的大千世界

   直接繼承關係:

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
        
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable { }

   3.1 靜態方法

    private static Class<?> javaxInjectProviderClass = null;

    static {
        try {
            javaxInjectProviderClass =
                    ClassUtils.forName("javax.inject.Provider", DefaultListableBeanFactory.class.getClassLoader());
        }
        catch (ClassNotFoundException ex) {
            // JSR-330 API not available - Provider interface simply not supported then.
        }
    }

spring提供一些實用的綜合工具類如ClassUtils,ClassUtils提供了對類的實用方法,主要用在框架內部,想要了解更全面的類的工具方法可以參考apache commons lang。

Commons Lang
The standard Java libraries fail to provide enough methods for manipulation of its core classes. Apache Commons Lang provides these extra methods.

Lang provides a host of helper utilities for the java.lang API, notably String manipulation methods, basic numerical methods, object reflection, concurrency, creation and serialization and System properties. Additionally it contains basic enhancements to java.util.Date and a series of utilities dedicated to help with building methods, such as hashCode, toString and equals
ClassUtils.forName方法是class.forname的重寫,返回一個類的例項,區別請參考原始碼。

上述靜態方法中返回了javax.inject.Provider的一個例項,那麼我們揭開javax.inject.Provider的面紗看看它到底起了什麼作用。

語法:public interface Provider<T>

提供了一個 T的例項. 通常作為一個依賴注入容器器的父介面. 可以注入任何型別的 T, 當然也可以注入 Provider<T>. 相對於直接注入 T,注入 Provider<T>有如下作用:

  • 檢索多個例項.
  • 延遲或者選擇性的檢索一個例項.
  • 打破迴圈依賴.
  • 抽象的scope,可以從一個包含scope的更小的scope中檢索一個例項。

例項程式碼:

   class Car {
     @Inject Car(Provider<Seat> seatProvider) {
       Seat driver = seatProvider.get();
       Seat passenger = seatProvider.get();
       ...
     }
   }

3.2 繼承自AbstractAutowireCapableBeanFactory的方法:

AbstractAutowireCapableBeanFactory的作用:

提供bean的建立 (有construct方法), 屬性注值, 繫結 (包括自動繫結)和初始化.

處理執行時bean引用, 解析管理的集合, 呼叫初始化方法。

最主要的子類要實現的模板方法是 AutowireCapableBeanFactory.resolveDependency(DependencyDescriptor, String, Set, TypeConverter), 這個方法用來實現型別的自動繫結.

在DefaultListableBeanFactory中實現了AbstractAutowireCapableBeanFactory.copyConfigurationFrom

    @Override
    public void copyConfigurationFrom(ConfigurableBeanFactory otherFactory) {
        super.copyConfigurationFrom(otherFactory);
        if (otherFactory instanceof DefaultListableBeanFactory) {
            DefaultListableBeanFactory otherListableFactory = (DefaultListableBeanFactory) otherFactory;
            this.allowBeanDefinitionOverriding = otherListableFactory.allowBeanDefinitionOverriding;
            this.allowEagerClassLoading = otherListableFactory.allowEagerClassLoading;
            this.autowireCandidateResolver = otherListableFactory.autowireCandidateResolver;
            this.resolvableDependencies.putAll(otherListableFactory.resolvableDependencies);
        }
    }

其中:

allowBeanDefinitionOverriding定義了是否允許同名的不同bean definition再次進行註冊;

allowEagerClassLoading 定義了是否允許eager類(相對於lazy)的載入,甚至延遲初始化的bean的載入。

autowireCandidateResolver是一個策略介面,用來決定一個特定的bean definition 是否滿足做一個特定依賴的自動繫結的候選項,方法如下所示:

 
 
//SimpleAutowireCandidateResolver implements AutowireCandidateResolver
@Override 
public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) { 
return bdHolder.getBeanDefinition().isAutowireCandidate(); }
//GenericTypeAwareAutowireCandidateResolver implements AutowireCandidateResolver
@Override 
public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
if (!bdHolder.getBeanDefinition().isAutowireCandidate()) { // if explicitly false, do not proceed with any other checks return false; } return (descriptor == null || checkGenericTypeMatch(bdHolder, descriptor)); }

resolvableDependencies:定義了依賴型別和其對應的自動繫結值的鍵值對集合。

AbstractAutowireCapableBeanFactory的copyConfigurationFrom方法:

    @Override
    public void copyConfigurationFrom(ConfigurableBeanFactory otherFactory) {
        super.copyConfigurationFrom(otherFactory);
        if (otherFactory instanceof AbstractAutowireCapableBeanFactory) {
            AbstractAutowireCapableBeanFactory otherAutowireFactory =
                    (AbstractAutowireCapableBeanFactory) otherFactory;
            this.instantiationStrategy = otherAutowireFactory.instantiationStrategy;
            this.allowCircularReferences = otherAutowireFactory.allowCircularReferences;
            this.ignoredDependencyTypes.addAll(otherAutowireFactory.ignoredDependencyTypes);
            this.ignoredDependencyInterfaces.addAll(otherAutowireFactory.ignoredDependencyInterfaces);
        }
    }

其中,instantiationStrategy 為建立bean 例項的策略,預設值:

private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();

allowCircularReferences 確定是否自動嘗試去解析迴圈引用的bean。

ignoredDependencyTypes 定義了在依賴檢查和自動繫結時要忽略的依賴型別,是一組類物件,例如string,預設為沒有。

ignoredDependencyInterfaces  定義了在依賴檢查和自動繫結時要忽略的依賴介面,是一組類物件,預設情況下,只有beanFactory介面被忽略。

父類AbstractBeanFactory的copyConfigurationFrom的實現如下:

    @Override
    public void copyConfigurationFrom(ConfigurableBeanFactory otherFactory) {
        Assert.notNull(otherFactory, "BeanFactory must not be null");
        setBeanClassLoader(otherFactory.getBeanClassLoader());
        setCacheBeanMetadata(otherFactory.isCacheBeanMetadata());
        setBeanExpressionResolver(otherFactory.getBeanExpressionResolver());
        if (otherFactory instanceof AbstractBeanFactory) {
            AbstractBeanFactory otherAbstractFactory = (AbstractBeanFactory) otherFactory;
            this.customEditors.putAll(otherAbstractFactory.customEditors);
            this.propertyEditorRegistrars.addAll(otherAbstractFactory.propertyEditorRegistrars);
            this.beanPostProcessors.addAll(otherAbstractFactory.beanPostProcessors);
            this.hasInstantiationAwareBeanPostProcessors = this.hasInstantiationAwareBeanPostProcessors ||
                    otherAbstractFactory.hasInstantiationAwareBeanPostProcessors;
            this.hasDestructionAwareBeanPostProcessors = this.hasDestructionAwareBeanPostProcessors ||
                    otherAbstractFactory.hasDestructionAwareBeanPostProcessors;
            this.scopes.putAll(otherAbstractFactory.scopes);
            this.securityContextProvider = otherAbstractFactory.securityContextProvider;
        }
        else {
            setTypeConverter(otherFactory.getTypeConverter());
        }
    }

其中

customEditors 是自定義的屬性編輯器,適用於該beanFactory的所有bean。
propertyEditorRegistrars屬性編輯器的註冊器,使用於該beanFactory的所有bean。
beanPostProcessors 建立bean時應用的beanPostProcessors。
hasInstantiationAwareBeanPostProcessors 表明是否註冊有任何的InstantiationAwareBeanPostProcessors。
hasDestructionAwareBeanPostProcessors
表明是否註冊有任何的DestructionAwareBeanPostProcessors
scopes:域識別符號和對應域的鍵值對集合。

securityContextProvider 執行SecurityManager時使用的security context。

3.3 繼承自ListableBeanFactory介面的方法
ListableBeanFactory是beanFactory介面的擴充套件介面,它可以列舉所有的bean例項,而不是客戶端通過名稱一個一個的查詢得出所有的例項。要預載入所有的bean定義的beanfactory可以實現這個介面來。該 介面定義了訪問容器中Bean基本資訊的若干方法,如檢視Bean的個數、獲取某一型別Bean的配置名、檢視容器中是否包括某一Bean等方法;
containsBeanDefinition(String beanName) 
Check if this bean factory contains a bean definition with the given name. 

findAnnotationOnBean(String beanName, Class<A> annotationType) 
Find a Annotation of annotationType on the specified bean, traversing its interfaces and super classes if no annotation can be found on the given class itself. 

getBeanDefinitionCount() 
Return the number of beans defined in the factory. 

getBeanDefinitionNames() 
Return the names of all beans defined in this factory. 

getBeanNamesForType(Class<?> type) 
Return the names of beans matching the given type (including subclasses), judging from either bean definitions or the value of getObjectType in the case of FactoryBeans. 

getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) 
Return the names of beans matching the given type (including subclasses), judging from either bean definitions or the value of getObjectType in the case of FactoryBeans. 

getBeansOfType(Class<T> type) 
Return the bean instances that match the given object type (including subclasses), judging from either bean definitions or the value of getObjectType in the case of FactoryBeans. 

getBeansOfType(Class<T> type, boolean includeNonSingletons, boolean allowEagerInit) 
Return the bean instances that match the given object type (including subclasses), judging from either bean definitions or the value of getObjectType in the case of FactoryBeans. 

getBeansWithAnnotation(Class<? extends Annotation> annotationType) 
Find all beans whose Class has the supplied Annotation type.

3.4 繼承自ConfigurableListableBeanFactory介面的方法
ConfigurableListableBeanFactory 它同時繼承了ListableBeanFactory,AutowireCapableBeanFactory和ConfigurableBeanFactory,提供了對bean定義的分析和修改的便利方法,同時也提供了對單例的預例項化。
void freezeConfiguration() 
Freeze all bean definitions, signalling that the registered bean definitions will not be modified or post-processed any further. 

BeanDefinition getBeanDefinition(String beanName) 
Return the registered BeanDefinition for the specified bean, allowing access to its property values and constructor argument value (which can be modified during bean factory post-processing). 

void ignoreDependencyInterface(Class<?> ifc) 
Ignore the given dependency interface for autowiring. 

void ignoreDependencyType(Class<?> type) 
Ignore the given dependency type for autowiring: for example, String. 

boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor) 
Determine whether the specified bean qualifies as an autowire candidate, to be injected into other beans which declare a dependency of matching type. 

boolean isConfigurationFrozen() 
Return whether this factory's bean definitions are frozen, i.e. 

void preInstantiateSingletons() 
Ensure that all non-lazy-init singletons are instantiated, also considering FactoryBeans. 

void registerResolvableDependency(Class<?> dependencyType, Object autowiredValue) 
Register a special dependency type with corresponding autowired value. 
3.5 繼承自BeanDefinitionRegistry介面的方法
BeanDefinitionRegistry:Spring配置檔案中每一個<bean>節點元素在Spring容器裡都通過一個BeanDefinition物件表示,它描述了Bean的配置資訊。而BeanDefinition Registry介面提供了向容器手工註冊BeanDefinition物件的方法。
boolean containsBeanDefinition(String beanName) 
Check if this registry contains a bean definition with the given name. 

BeanDefinition getBeanDefinition(String beanName) 
Return the BeanDefinition for the given bean name. 

int getBeanDefinitionCount() 
Return the number of beans defined in the registry. 

String[] getBeanDefinitionNames() 
Return the names of all beans defined in this registry. 

boolean isBeanNameInUse(String beanName) 
Determine whether the given bean name is already in use within this registry, i.e. 

void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) 
Register a new bean definition with this registry. 

void removeBeanDefinition(String beanName) 
Remove the BeanDefinition for the given name. 

3.6 序列化支援
 private void writeObject(java.io.ObjectOutputStream out)throws IOException
 private void readObject(java.io.ObjectInputStream in)throws IOException, ClassNotFoundException;
 private void readObjectNoData()throws ObjectStreamException;

4 小結:
spring Ioc容器的實現,從根源上是beanfactory,但真正可以作為一個可以獨立使用的ioc容器還是DefaultListableBeanFactory,因此可以這麼說,
DefaultListableBeanFactory 是整個spring ioc的始祖,研究透它的前生今世對我們理解spring ioc的概念有著重要的作用。
DefaultListableBeanFactory功能的實現是通過實現特定功能的介面來完成。
AbstractAutowireCapableBeanFactory 實現屬性的自動繫結功能。
ConfigurableListableBeanFactory提供了對bean定義的分析和修改的便利方法,同時也提供了對單例的預例項化。

  ListableBeanFactory提供列舉所有的bean例項,而不是客戶端通過名稱一個一個的查詢得出所有的例項。

BeanDefinitionRegistry 提供了beanDefinition的管理。