在基于ClassPathXmlApplicationContext创建BeanFactory时,我们从代码里看到,创建的BeanFactory的类型是DefaultListableBeanFactory。
下面我们来分析下DefaultListableBeanFactory的继承结构,以及基于这个结构下,每个父类接口的用途。
具体UML类图实现如下:
下面开始从顶层实现类开始,依次向下逐层分析:
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等。
具体实现的方法可参照下图:
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等相关方法,具体定义的方法可参照下图:
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并在初始化前后调用相应的后置处理器,解析依赖,完成依赖注入等功能。
具体内部方法参照下图:
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);
}
具体实现的方法如下所示,主要围绕上面定义的属性进行读写管理:
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();
}