文章目录
前言
体能状态先于精神状态,习惯先于决心,聚焦先于喜好。
DefaultListableBeanFactory
org.springframework.beans.factory.support.DefaultListableBeanFactory
DefaultListableBeanFactory 是一个非常重要的 BeanFactory,是Spring 中的一个核心类。
DefaultListableBeanFactory 是Spring中默认的ListableBeanFactory和BeanDefinitionRegistry的实现类,已经包含了比较全面的功能,可以作为单例工厂直接使用,也可以将其作为父类进行扩展。
典型的应用方法是,在调用相关的SpringBean之前,通过Bean定义文件对Bean进行注册。你不用担心这个前置操作会消耗太多性能,因为通过操作本地的一个包含了Bean定义信息的不可变对象来注册Bean还是很快的。
DefaultListableBeanFactory 中的一些常量
其中有几个变量我们单独说下:
默认情况后,允许重复加载同名bean,后面的覆盖前面的。
默认情况下,允许立即加载遇到的bean,即使配置了懒加载。
private static Class<?> javaUtilOptionalClass = null;
private static Class<?> javaxInjectProviderClass = null;
static {
try {
javaUtilOptionalClass =
ClassUtils.forName("java.util.Optional", DefaultListableBeanFactory.class.getClassLoader());
}
catch (ClassNotFoundException ex) {
// Java 8 not available - Optional references simply not supported then.
}
try {
javaxInjectProviderClass =
ClassUtils.forName("javax.inject.Provider", DefaultListableBeanFactory.class.getClassLoader());
}
catch (ClassNotFoundException ex) {
// JSR-330 API not available - Provider interface simply not supported then.
}
}
/** Map:key:序列化ID,value:DefaultListableBeanFactory实例对象*/
private static final Map<String, Reference<DefaultListableBeanFactory>> serializableFactories =
new ConcurrentHashMap<String, Reference<DefaultListableBeanFactory>>(8);
/** 该 工厂 的可选id,用于序列化 */
private String serializationId;
/** 是否允许同名 bean 定义的从新注册,即同名bean定义,后面的注册能否覆盖之前的,默认是可以 */
private boolean allowBeanDefinitionOverriding = true;
/** 是否允许 eager class loading(立即加载) 包括对于 lazy-init beans,默认是允许 */
private boolean allowEagerClassLoading = true;
/** 可选的用于依赖集合和数组的顺序比较器 */
private Comparator<Object> dependencyComparator;
/**用于检测 Bean 是否有 自动注入请求 */
private AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver();
/** 保存 依赖类型 和 依赖的对象 的map */
private final Map<Class<?>, Object> resolvableDependencies = new ConcurrentHashMap<Class<?>, Object>(16);
/** 保存“bean的定义”的对象的Map,key:bean的名字, value:定义bean的相关对象 */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(256);
/**map ,保存key:依赖类型,value:单例和非单例 bean的名字*/
private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64);
/** map,key:依赖类型,value:单例bean的名字*/
private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64);
/** list:bean定义的名字,按照注册顺序保存 */
private volatile List<String> beanDefinitionNames = new ArrayList<String>(256);
/** list:手工注册单例bean的名字,按照注册顺序 */
private volatile Set<String> manualSingletonNames = new LinkedHashSet<String>(16);
/** 为了冻结配置 提供的 bean名字的缓存数组 */
private volatile String[] frozenBeanDefinitionNames;
/** 是否允许bean定义的元数据被缓存,以用于所有的bean,默认是否 */
private volatile boolean configurationFrozen = false;
AbstractAutowireCapableBeanFactory
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory 是 DefaultListableBeanFactory 的父类。
有几个比较重要的变量:
默认允许循环依赖。
默认的实例化策略为 cglib动态代理,即cglib为代理类生成子类的方式对方法进行注入。
默认情况下,如果循环依赖失败,不允许注入原始的bean——比如这个bean经过AOP包装。
有些类比如String不会被检测和注入依赖。
有些接口也不会被检测和注入依赖, 默认只有 BeanFactory interface,但是在 DefaultListableBeanFactory 中其实增加了 BeanNameAware、BeanFactoryAware和BeanClassLoaderAware 三个接口要被忽略
未完成实例化的bean会被先保存在 factoryBeanInstanceCache 这个缓存map中。
AbstractAutowireCapableBeanFactory 全局变量介绍
这里我们看下 AbstractAutowireCapableBeanFactory 中的全局变量
/** 创建 bean实例的策略
默认使用 Cglib 动态代理,即以动态生成子类的方式对方法进行注入*/
private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();
/** 方法参数名称的解析策略 */
private ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
/** 是否允许循环依赖的 beans,默认是允许的 */
private boolean allowCircularReferences = true;
/**
* 是否在循环依赖的时候尝试将 bean 的原始对象注入到参数中,即使这个bean是被包装的(比如AOP),默认是否
*/
private boolean allowRawInjectionDespiteWrapping = false;
/**
* 设置需要忽略依赖检测和注入的类型,比如 String
*/
private final Set<Class<?>> ignoredDependencyTypes = new HashSet<Class<?>>();
/**
* 设置需要忽略依赖和注入的接口,默认只有 BeanFactory interface,但是在 DefaultListableBeanFactory 中其实增加了 BeanNameAware、BeanFactoryAware和BeanClassLoaderAware 三个接口要被忽略
*/
private final Set<Class<?>> ignoredDependencyInterfaces = new HashSet<Class<?>>();
/** 没有完成实例化的 FactoryBean 缓存map,key:FactoryBean 名称 ,value:BeanWrapper */
private final Map<String, BeanWrapper> factoryBeanInstanceCache =
new ConcurrentHashMap<String, BeanWrapper>(16);
/** 过滤了的属性描述器 缓存map, key:bean Class,value:PropertyDescriptor 数据,最多256个 */
private final ConcurrentMap<Class<?>, PropertyDescriptor[]> filteredPropertyDescriptorsCache =
new ConcurrentHashMap<Class<?>, PropertyDescriptor[]>(256);
Spring 关于循环依赖的两个常量
AbstractAutowireCapableBeanFactory 中关于 循环依赖的变量 allowCircularReferences 和 allowRawInjectionDespiteWrapping 。
实时上,Spring 仅允许单例模式下的允许依赖,并且在循环依赖无法完成注入时,默认不采取原始类型对象的注入。
/** 是否允许循环依赖的 beans,默认是允许的 */
private boolean allowCircularReferences = true;
/**
* 是否在循环依赖的时候尝试将 bean 的原始对象注入到参数中,即使这个bean是被包装的(比如AOP),默认是否
*/
private boolean allowRawInjectionDespiteWrapping = false;