3.1、Spring源码学习:认识 DefaultListableBeanFactory

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/bestcxx/article/details/100182604

前言

体能状态先于精神状态,习惯先于决心,聚焦先于喜好。

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;

猜你喜欢

转载自blog.csdn.net/bestcxx/article/details/100182604