【Spring源码阅读】 DefaultListableBeanFactory继承结构讲解分析

 2019-10-17 22:00  阅读(1026)
文章分类:Spring boot

在基于ClassPathXmlApplicationContext创建BeanFactory时,我们从代码里看到,创建的BeanFactory的类型是DefaultListableBeanFactory。
下面我们来分析下DefaultListableBeanFactory的继承结构,以及基于这个结构下,每个父类接口的用途。
具体UML类图实现如下:
20191017100359\_1.png
下面开始从顶层实现类开始,依次向下逐层分析:

DefaultListableBeanFactory实现

实现接口向上可以追述至BeanFacotry,向下还有XmlBeanFactory实现,但从整个继承结构来看,从DefaultListableBeanFactory开始可以作为独立的IOC容器。
分析源码,在DefaultListableBeanFactory中定义了以下属性

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
            implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
        /** 存储映射serializedId->DefaultListableBeanFactory的弱引用实例*/
        private static final Map<String, Reference<DefaultListableBeanFactory>> serializableFactories =
                new ConcurrentHashMap<String, Reference<DefaultListableBeanFactory>>(8);

        /** 当前工厂的可选序列化id */
        private String serializationId;

        /** 是否允许同名的不同bean definition再次进行注册 * 在注册BeanDefinition发现存在同名BeanDefinition时,会检查当前变量,如果为false会抛出BeanDefinitionStoreException */
        private boolean allowBeanDefinitionOverriding = true;

        /** 是否允许eager类(相对于lazy)的加载,甚至延迟初始化的bean的加载, * 主要用于在调用doGetBeanNamesForType辅助寻找符合type要求的beanName */
        private boolean allowEagerClassLoading = true;

        /**是一个策略接口,用来决定一个特定的bean definition 是否满足做一个特定依赖的自动绑定的候选项 * 里面定义了isAutowireCandidate方法用来判断一个Bean是否参与自动装配候选以及getSuggestedValue方法找出最佳候选Bean*/
        private AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver();

        /** 定义了依赖类型和其对应的依赖注入对象键值对集合。 */
        private final Map<Class<?>, Object> resolvableDependencies = new HashMap<Class<?>, Object>(16);

        /** 定义了BeanName->BeanDefinition的映射关系 */
        private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(64);

        /** 定义了依赖类型->BeanNames的映射关系,包括单例和原型Bean * 具体存储原理是先根据BeanName读取beanDefinitionNames对象或frozenBeanDefinitionNames对象 * 再调用getMergedLocalBeanDefinition(beanName)方法拿到具体的BeanDefinition,比对BeanClass,满足要求的都保存到List统一返回*/
        private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64);

        /** 类似于allBeanNamesByType,不过只包含单例Bean */
        private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64);

        /** 根据注册顺序,存储所有的beanDefinitionName,即beanName */
        private final List<String> beanDefinitionNames = new ArrayList<String>(64);

        /** 配置是否冻结 在初始化完BeanFactory,开始初始化所有单例非懒加载Bean时调用finishBeanFactoryInitialization方法进行冻结*/
        private boolean configurationFrozen = false;

        /** 在设置上一布尔变量同时缓存当前时刻的所有beanDefinitionNames到当前属性 */
        private String[] frozenBeanDefinitionNames;

    }

在DefaultListableBeanFactory内部,实现了ListableBeanFactory、ConfigurableListableBeanFactory、BeanDefinitionRegistry的相关接口,同时还实现了解析依赖,查到最佳的依赖注入BeanName等。
具体实现的方法可参照下图:
20191017100359\_2.png

ConfigurableListableBeanFactory

ConfigurableListableBeanFactory定义bean definition的解析,修改等方法功能,还定义了初始化非懒加载单例Bean的核心方法preInstantiateSingletons.
具体接口定义如下:

public interface ConfigurableListableBeanFactory
            extends ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory {

        /** * 忽略指定类型的自动装配 * @param type 要忽略的依赖类型 */
        void ignoreDependencyType(Class<?> type);

        /** * 在自动装配时忽略该接口实现类中和setter方法入参相同的类型 * 在进行依赖注入时,会获取待注入属性的set方法,如果set方法的入参实现了本接口,会忽略该属性的依赖注入 * 具体参考https://www.jianshu.com/p/3c7e0608ff1f * @param ifc 要进行据略的接口 */
        void ignoreDependencyInterface(Class<?> ifc);

        /** * 建议一个依赖类型->自动装配Bean的映射关系 * @param dependencyType 依赖类型 * @param autowiredValue 对应的装配实例,也可以是ObjectFactory的实现,会调用其中的getObject方法完成拦截在. */
        void registerResolvableDependency(Class<?> dependencyType, Object autowiredValue);

        /** * 判断特定的bean是否可以作为一个自动装配的候选Bean * @param beanName 待检查的BeanName * @param descriptor 待解析的依赖参数的描述器 * @return 返回是否可以作为候选Bean * @throws NoSuchBeanDefinitionException 如果没有BeanName对应的BeanDefinition */
        boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor)
                throws NoSuchBeanDefinitionException;

        /** * 根据BeanName获取具体的BeanDefinition */
        BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

        /** * 冻结配置 */
        void freezeConfiguration();

        /** * 判断相关配置是否已冻结 */
        boolean isConfigurationFrozen();

        /** * 初始化所有非懒加载的单例Bean,相应的通过调用destroySingletons方法销毁本方法注册的单例 */
        void preInstantiateSingletons() throws BeansException;

    }

ListableBeanFactory

继承自BeanFactory接口,定义了迭代枚举容器Bean实例的相关方法,具体定义如下:

public interface ListableBeanFactory extends BeanFactory {

        /** * 容器是否定义了指定beanName的 */
        boolean containsBeanDefinition(String beanName);

        /** * 获取BeanDefinition数量 */
        int getBeanDefinitionCount();

        /** * 获取所有的BeanDefinition的BeanName */
        String[] getBeanDefinitionNames();

        /** * 获取指定类型的所有BeanNames,默认包含非单例(原型Bean),允许提前初始化,可能会导致实现FactoryBean接口的Bean提前初始化 */
        String[] getBeanNamesForType(Class<?> type);

        /** * 获取指定类型的所有BeanNames * @param type 要获取BeanName的类型 * @param includeNonSingletons 是否包含包含非单例(原型Bean) * @param allowEagerInit 允许提前初始化,可能会导致实现FactoryBean接口的Bean提前初始化 */
        String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);

        /** * 获取指定类型的的beanName->bean实例映射,默认包含非单例(原型Bean),允许提前初始化,可能会导致实现FactoryBean接口的Bean提前初始化 */
        <T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException;

        /** * 获取指定类型的的beanName->bean实例映射 * @param type 要获取BeanName的类型 * @param includeNonSingletons 是否包含包含非单例(原型Bean) * @param allowEagerInit 允许提前初始化,可能会导致实现FactoryBean接口的Bean提前初始化 */
        <T> Map<String, T> getBeansOfType(Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
                throws BeansException;

        /** * 获取带有指定注解类型的beanName->bean实例映射 */
        Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType)
                throws BeansException;

        /** * 根据注解类型和beanName获取相关的Bean注解实例 */
        <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType);

    }

AbstractAutowireCapableBeanFactory

在本类中定义了Spring容器的几乎最核心的实现逻辑,包括实例化bean和依赖注入的具体实现等。
在本类,基本的属性定义如下所示:

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
            implements AutowireCapableBeanFactory {

        /** 实例化Bean的策略,默认是CglibSubclassingInstantiationStrategy, * 对于实现了lookup-method或replace-method,会通过当前策略生成的CGLIB代理类增强调用相应的方法*/
        private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();

        /** 默认的方法参数名字解析策略 */
        private ParameterNameDiscoverer parameterNameDiscoverer = new LocalVariableTableParameterNameDiscoverer();

        /** 是否允许出现循环引用,如果为false,在实例化Bean后不会放入单例工厂中以提前暴露给其他Bean依赖注入 */
        private boolean allowCircularReferences = true;

        /** * 是否在循环引用的情况下注入原始bean实例,即使注入的bean最终被包装。 */
        private boolean allowRawInjectionDespiteWrapping = false;

        /** * 存储在依赖注入时要忽略的类 */
        private final Set<Class<?>> ignoredDependencyTypes = new HashSet<Class<?>>();

        /** * 存储在自动装配时,要忽略的在setter方法中实现本接口的入参 */
        private final Set<Class<?>> ignoredDependencyInterfaces = new HashSet<Class<?>>();

        /** 缓存FactoryBean name 到具体的FactoryBean实例(具体表现为映射BeanWrapper)*/
        private final Map<String, BeanWrapper> factoryBeanInstanceCache =
                new ConcurrentHashMap<String, BeanWrapper>(16);

        /** 缓存根据ignoredDependencyTypes,ignoredDependencyInterfaces条件过滤的特定Bean类的属性描述器*/
        private final Map<Class<?>, PropertyDescriptor[]> filteredPropertyDescriptorsCache =
                new ConcurrentHashMap<Class<?>, PropertyDescriptor[]>(64);
    }

AbstractAutowireCapableBeanFactory实现的方法相当多而复杂,总结来说,AbstractAutowireCapableBeanFactory实现了Spring容器实例化、依赖注入Bean相关属性、初始化Bean等相关方法,具体定义的方法可参照下图:
20191017100359\_3.png

AutowireCapableBeanFactory

定义提供了BeanFacotry实现了依赖注入的功能,定义了依赖注入类型的相关枚举,内部包含以下常量属性:

public interface AutowireCapableBeanFactory extends BeanFactory {

        /** * 不使用自动装配,不影响通过xml配置或注解等方式的显式依赖注入配置 */
        int AUTOWIRE_NO = 0;

        /** * 在初始化容器内Bean的时候,检索出Bean内可以进行依赖注入的属性,然后根据名字检索容器内的Bean进行注入 */
        int AUTOWIRE_BY_NAME = 1;

        /** * 在初始化容器内Bean的时候,检索出Bean内可以进行依赖注入的属性,然后根据类型检索容器内的Bean进行注入 */
        int AUTOWIRE_BY_TYPE = 2;

        /** * 检索最符合的构造方法,对构造函数内的入参进行依赖注入,再传入构造函数 */
        int AUTOWIRE_CONSTRUCTOR = 3;

        /** * 自动探测,如果Bean内有无参构造函数,则用AUTOWIRE_BY_TYPE,否则用AUTOWIRE_CONSTRUCTOR */
        @Deprecated
        int AUTOWIRE_AUTODETECT = 4;

    }

AutowireCapableBeanFactory接口定义的方法主要涵盖创建、初始化Bean并在初始化前后调用相应的后置处理器,解析依赖,完成依赖注入等功能。
具体内部方法参照下图:
20191017100359\_4.png

AbstractBeanFactory

BeanFactory的抽象实现,继承自FactoryBeanRegistrySupport。提供了单例对象管理、父子容器管理,BeanDefinition管理和FactoryBean注册管理等相关功能,AbstractBeanFactory具体定义的属性如下:

public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {

        /** 父容器,为BeanFactory提供继承能力 */
        private BeanFactory parentBeanFactory;

        /** 必要时用于解析加载bean类,当tempClassLoader=null时使用 */
        private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();

        /**必要时用于临时解析加载bean类,在预加载非拦截在单例Bean的冻结配置前使用*/
        private ClassLoader tempClassLoader;

        /** 是否缓存bean元数据,或者每次访问重新获取,如果为true,每次调用getMergedBeanDefinition后必要时会缓存到mergedBeanDefinitions */
        private boolean cacheBeanMetadata = true;

        /** 表达式解析策略,用于解析beanDefinition中的表达式如SpEL等 */
        private BeanExpressionResolver beanExpressionResolver;

        /** 在属性编辑(读写)过程通过ConversionService完成属性的类型转换,默认全部属性为String类型,最终转换成各种对象类型*/
        private ConversionService conversionService;

        /** 自定义属性编辑器注册商,持有属性编辑器的注册器,通过调用registerCustomEditors方法完成批量注册拓展的自定义属性编辑器的逻辑*/
        private final Set<PropertyEditorRegistrar> propertyEditorRegistrars =
                new LinkedHashSet<PropertyEditorRegistrar>(4);

        /** 自定义TypeConverter,重写默认的PropertyEditor机制,定义了属性转换的机制 */
        private TypeConverter typeConverter;

        /** 自定义属性编辑器,用于编辑容器内的Bean属性 * 调用链是通过createBean->doCreateBean->populateBean->applyPropertyValues->TypeConverter.convertIfNecessary进行 */
        private final Map<Class<?>, Class<? extends PropertyEditor>> customEditors =
                new HashMap<Class<?>, Class<? extends PropertyEditor>>(4);

        /** 用于诸如注解属性的字符串解析器 */
        private final List<StringValueResolver> embeddedValueResolvers = new LinkedList<StringValueResolver>();

        /** 存储实例化和初始化Bean过程用到的Bean后置处理器BeanPostProcessors to apply in createBean */
        private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<BeanPostProcessor>();

        /** 标志容器内是否注册了InstantiationAwareBeanPostProcessors */
        private boolean hasInstantiationAwareBeanPostProcessors;

        /** 标志容器内是否注册了destructionAwareBeanPostProcessors */
        private boolean hasDestructionAwareBeanPostProcessors;

        /** 建立字符串类型->Scope的映射关系 * 具体用例如registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope()) * */
        private final Map<String, Scope> scopes = new HashMap<String, Scope>(8);

        /** 容器内运行的安全上下文的提供者 */
        private SecurityContextProvider securityContextProvider;

        /** 建立BeanName->RootBeanDefinition的映射关系 */
        private final Map<String, RootBeanDefinition> mergedBeanDefinitions =
                new ConcurrentHashMap<String, RootBeanDefinition>(64);

        /** 记录特定BeanName的bean已经创建过至少一次 */
        private final Map<String, Boolean> alreadyCreated = new ConcurrentHashMap<String, Boolean>(64);

        /** 记录当前处于创建状态的Bean */
        private final ThreadLocal<Object> prototypesCurrentlyInCreation =
                new NamedThreadLocal<Object>("Prototype beans currently in creation");
    }

ConfigurableBeanFactory

提供配置管理Bean的能力,定义了Bean作用域的基础类型,包括singleton和prototype,继承自HierarchicalBeanFactory, SingletonBeanRegistry,具有父子容器继承和单例Bean注册等相关能力

FactoryBeanRegistrySupport

提供了FacotryBean类型Bean的注册管理,定义了一个ConcurrentHashMap建立了beanName->FactoryBean的缓存。
具体实现如下:

public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry {

        /** 建立BeanName->factoryBeanObject的缓存映射 */
        private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<String, Object>(16);

        /** * 调用factoryBean.getObjectType()获取实现了FactoryBean接口的相应实例方法. */
        protected Class<?> getTypeForFactoryBean(final FactoryBean<?> factoryBean);

        /** * 尝试从缓存中获取FactoryBeanObject */
        protected Object getCachedObjectForFactoryBean(String beanName);

        /** * 获取当前factory的实际实例对象,会先尝试从缓存获取,再通过调用doGetObjectFromFactoryBean获取 */
        protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess);

        /** * 真正获取对象的方法,通过调用factory.getObject() */
        private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
                throws BeanCreationException;

        /** * 默认实现是直接返回入参Object,子类可以自行拓展,如添加Bean后置处理器逻辑等 */
        protected Object postProcessObjectFromFactoryBean(Object object, String beanName) throws BeansException {
            return object;
        }

        /** * 判断beanInstance是否是FactoryBean实例,如果是则进行类型转换返回. */
        protected FactoryBean<?> getFactoryBean(String beanName, Object beanInstance) throws BeansException;

        /** * 先调用父类removeSingleton,并尝试从当前factoryBean缓存中移除特定Bean */
        @Override
        protected void removeSingleton(String beanName);

        /** * 调用jdk源码AccessController.getContext()获取安全上线文访问器 */
        protected AccessControlContext getAccessControlContext();

    }

DefaultSingletonBeanRegistry

SingletonBeanRegistry接口的默认实现,继承自SimpleAliasRegistry类,具有别名、单例Bean注册管理的相关能力。
具体定义如下:

public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {

        /** * 标记一个null值,多用于在Concurrent Map中作值存在 */
        protected static final Object NULL_OBJECT = new Object();

        /** 子类可访问的日志管理器 */
        protected final Log logger = LogFactory.getLog(getClass());

        /** 下面三个属性定义了单例初始化过程的"三级缓存" * 在Bean实例化后存储在三级缓存singletonFactories中, * 当需要时调用ObjectFactory.getObject延迟获取Bean实例,并放入二级缓存earlySingletonObjects * 当Bean初始化结束后,从二级缓存earlySingletonObjects移除,放入一级缓存singletonObjects中 * 具体获取顺序,singletonObjects->earlySingletonObjects->singletonFactories **/

        /** 一级缓存 映射beanName->单例对象*/
        private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64);

        /** 二级缓存 映射beanName->ObjectFactory*/
        private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);

        /** 三级缓存 映射beanName->早期单例对象,即未完整初始化的单例对象*/
        private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);

        /** 根据单例Bean的注入顺序,存储单例BeanName */
        private final Set<String> registeredSingletons = new LinkedHashSet<String>(64);

        /** 存储处于创建状态的BeanName */
        private final Map<String, Boolean> singletonsCurrentlyInCreation = new ConcurrentHashMap<String, Boolean>(16);

        /** 存储需要过滤创建状态检测的BeanName */
        private final Map<String, Boolean> inCreationCheckExclusions = new ConcurrentHashMap<String, Boolean>(16);

        /** 记录在尝试获取/创建单例过程中遇到的多层捕捉到的异常,最后统一抛出 */
        private Set<Exception> suppressedExceptions;

        /** 标志当前容器是否正在销毁容器内的所有单例对象 */
        private boolean singletonsCurrentlyInDestruction = false;

        /** 映射存储BeanName->实现了Disposable接口bean实例 */
        private final Map<String, Object> disposableBeans = new LinkedHashMap<String, Object>();

        /** 映射存储外部BeanName和嵌套Bean集合的映射关系 */
        private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<String, Set<String>>(16);

        /** 映射存储被依赖的BeanName和依赖BeanName集合的映射关系 */
        private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<String, Set<String>>(64);

        /** 存储关系和dependentBeanMap相仿映射存储依赖的BeanName和被依赖BeanName集合的映射关系 */
        private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<String, Set<String>>(64);
    }

具体实现的方法如下所示,主要围绕上面定义的属性进行读写管理:
20191017100359\_5.png

SimpleAliasRegistry

一个简单的别名注册中心,实现了AliasRegistry接口。
AliasRegistry接口内部定义了4个方法,包括注册、移除、判断特定BeanName是否为别名,获取特定name的所有可能别名(递归遍历过程的所有别名)等。内部定义了唯一的属性

// 存储别名->"真名"的映射关系,这里真名可能为另一个真名的别名
    private final Map<String, String> aliasMap = new ConcurrentHashMap<String, String>(16);

SingletonBeanRegistry

定义了单例Bean注册管理的相关方法,具体定义如下:

public interface SingletonBeanRegistry {

        /** * 注册指定beanName的单例对象 */
        void registerSingleton(String beanName, Object singletonObject);

        /** * 获取指定beanName的单例对象 */
        Object getSingleton(String beanName);

        /** * 判断是否包含指定beanName的单例对象 */
        boolean containsSingleton(String beanName);

        /** * 获取所有注册的单例对象beanName */
        String[] getSingletonNames();

        /** * 获取注册的单例个数 */
        int getSingletonCount();

    }

来源:[]()

点赞(0)
版权归原创作者所有,任何形式转载请联系作者; Java 技术驿站 >> 【Spring源码阅读】 DefaultListableBeanFactory继承结构讲解分析

相关推荐