SpringBean重要对象之BeanFactory的介绍

一、BeanFactory简介

BeanFactory接口是IOC容器要实现的最基础的接口,其是主要作用是,管理bean的加载、实例化,控制bean的生命周期,维护bean之间的依赖关系。

如果说BeanFactory是Sping的心脏,那么ApplicationContext就是完整的身躯了。在Beanfactory中,很多功能需要以编程的方式实现,而在ApplicationContext中则可以通过配置的方式实现。

ApplicationContext接口作为BeanFactory的派生,除了提供BeanFactory所具有的功能外,还提供了更完整的框架功能:

1、继承MessageSource,因此支持国际化。

2、统一的资源文件访问方式。

3、提供在监听器中注册bean的事件。

4、同时加载多个配置文件。

5、载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层。

BeanFactory有3大子接口:ListableBeanFactoryHierarchicalBeanFactoryAutowireCapableBeanFactory 如下:
忽略ApplicationContext相关类

在这里插入图片描述

1、ListableBeanFactory

通过这个接口,我们可以获取多个 Bean,而最顶层 BeanFactory 接口的方法都是获取单个 Bean的,ApplicationContext 继承了 ListableBeanFactory

2、HierarchicalBeanFactory

这个接口主要是处理BeanFactory的子父级关系,也就是说我们可以在应用中起多个 BeanFactory,然后可以将各个 BeanFactory 设置为父子关系。ApplicationContext 继承了 HierarchicalBeanFactory

3、AutowireCapableBeanFactory

这个接口主要是用来处理Bean的自动装配,ApplicationContext 并没有继承它,ApplicationContext是通过组合的方式来使用它的如果你看到 ApplicationContext 接口定义中的最后一个方法 getAutowireCapableBeanFactory() 就知道了。

看到这里的时候,我觉得读者就应该站在高处看 ApplicationContext 了,ApplicationContext 继承自BeanFactory
但是它不应该被理解为 BeanFactory 的实现类,而是说其内部持有一个实例化的 BeanFactory(DefaultListableBeanFactory)
以后所有的 BeanFactory相关的操作其实是委托给这个实例来处理的

4、DefaultListableBeanFactory

ConfigurableListableBeanFactory 也是一个特殊的接口,看图,特殊之处在于它继承了第二层所有的三个接口,而 ApplicationContext 没有。我们可以看到 ConfigurableListableBeanFactory 只有一个实现类 DefaultListableBeanFactory,而且实现类 DefaultListableBeanFactory 还通过实现右边的 AbstractAutowireCapableBeanFactory 通吃了右路。所以结论就是,最底下这个家伙 DefaultListableBeanFactory 基本上是最牛的 BeanFactory 了,这也是为什么这边会使用这个类来实例化的原因。
在这里插入图片描述
DefaultListableBeanFactory父接口有,BeanDefinitionRegistry(bean注册中心),SingletonBeanRegistry(单例bean注册中心),BeanFactory (bean储存中心)。DefaultListableBeanFactory有储存和注册bean的作用,本文重点研究DefaultListableBeanFactory

二、DefaultListableBeanFactory的属性

DefaultListableBeanFactory的属性分布在,其几个父类中,为了方便查看,把他们和在一起

1、储存BeanDefinition

//储存springBean的容器,键是别名,值是BeanDefinition
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
//储存springBean名字的容器
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
/** 从bean名称映射到合并的RootBeanDefinition. */
private final Map<String, RootBeanDefinition> mergedBeanDefinitions = new ConcurrentHashMap<>(256);
/** 在冻结配置的情况下缓存的bean定义名称数组 */
private volatile String[] frozenBeanDefinitionNames;
// allowBeanDefinitionOverriding属性是指是否允对一个名字相同但definition不同进行重新注册,默认是true。
private boolean allowBeanDefinitionOverriding = true;
// 当前正在创建的bean的名称
private final ThreadLocal<Object> prototypesCurrentlyInCreation = new NamedThreadLocal<>("Prototype beans currently in creation");

2、储存和实例化对象

/**创建bean实例的策略。*/
private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();
//已创建至少一次的bean的名称
private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<>(256));
//是否缓存bean元数据,或者是否为每个访问重新获取它
private boolean cacheBeanMetadata = true;
//是否自动尝试解析bean之间的循环引用
private boolean allowCircularReferences = true
//是否为所有bean缓存bean定义元数据
private volatile boolean configurationFrozen = false;
//是否允许热加载即使是 懒加载设置
private boolean allowEagerClassLoading = true;
//是否在循环引用的情况下使用原始bean实例,即使注入的bean最终被包装了
private boolean allowRawInjectionDespiteWrapping = false;
//当前正在创建的bean的名称
private final Set<String> singletonsCurrentlyInCreation =Collections.newSetFromMap(new ConcurrentHashMap<>(16));
//*当前在创建检查中排除的bean的名称
private final Set<String> inCreationCheckExclusions =Collections.newSetFromMap(new ConcurrentHashMap<>(16));
//一次性bean实例:一次性实例的bean名称。
private final Map<String, Object> disposableBeans = new LinkedHashMap<>();
//包含bean名称之间的映射:bean名称到bean包含的一组bean名称
private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<>(16);
//在依赖bean名称之间映射:bean名称到依赖bean名称集
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
//在依赖bean名称之间映射:bean名称到bean依赖项的一组bean名称
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);

3、依赖检查和自动连接的忽略

// 依赖接口忽略依赖检查和自动连接,这是类对象的集合。默认情况下,只会忽略BeanFactory接口。(也就是实现了这些接口的Bean,不要Autowired自动装配了)
private final Set<Class<?>> ignoredDependencyInterfaces = new HashSet<>();
// 依赖类型忽略依赖检查和自动连接,这是类对象的集合:例如,String。默认是没有的。
private final Set<Class<?>> ignoredDependencyTypes = new HashSet<>();

ignoredDependencyInterfaces:忽略自动注入和ASrv中的setter方法入参相同的类
ignoredDependencyTypes: 忽略自动注入传入XX.Class的类型
这样来看ignoreDependencyType方法的生效范围更广
注:注入方式要求是default-autowire=“byType” 且只影响xml配置自动装配的依赖注入方式

该属性虽然在源码中有使用,但我觉得一般情况下不会用到它,一是因为在使用过程中都希望自动注入依赖,而是因为有@AutoWired注解,可以决定哪些依赖必须注入 , 二是因为目前使用最多最流行的是SpringBoot方式配置bean,xml方式将更少触及.
所以我觉得该方法仅仅在学习源代码时了解即可,不值得深究.

4、从依赖类型映射到对应的自动连接值

private final Map<Class<?>, Object> resolvableDependencies = new ConcurrentHashMap<>(16);

放在这里面的类,我们可以直接标注@Autowired使用,不用在我们自己注入到容器中;
DefaultListableBeanFactory中有BeanFactory,ResourceLoader,ApplicationEventPublisher,ApplicationContext

AnnotationConfigWebApplicationContext中还有ServletRequest,ServletResponse,HttpSession,WebRequest

@Component
public class Demo {
	@Autowired
	private BeanFactory beanFactory;

	public BeanFactory getBeanFactory(){
	    //可以获取容器使用的BeanFactory对象
		return beanFactory;
	}
}

5、储存单例对象

// 一级缓存
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
// 三级缓存
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
//二级缓存
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
//单例对象名字的集合
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
//判断单利对象是否要删除,如果true,就要删除上面三个单例对象的容器,默认fasle
private boolean singletonsCurrentlyInDestruction = false;
/** 按注册顺序排列的手动注册单例的名称列表. */
private volatile Set<String> manualSingletonNames = new LinkedHashSet<>(16);
// 用于依赖列表和数组的可选的OrderComparator
private Comparator<Object> dependencyComparator;
//解析器用于检查bean定义是否为自动连接的候选
private AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver();
// 单例和非单例bean的映射,依赖于依赖类型
private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<>(64);
//依赖类型的名称
private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<>(64);

6、后置处理器容器

/** bean后置处理器BeanPostProcessors的实现类 */
private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();
/**指示是否已注册任何InstantiationWarebeanPostprocessors. */
private volatile boolean hasInstantiationAwareBeanPostProcessors;
/** 指示是否已注册任何DestructionAwareBeanPostProcessors. */
private volatile boolean hasDestructionAwareBeanPostProcessors;

7、父容器

// 父bean工厂
private BeanFactory parentBeanFactory;

8、类型解析

//设置EL表达式解析器(Bean初始化完成后填充属性时会用到),spring3增加了表达式语言的支持,默认可以使用#{bean.xxx}的形式来调用相关属性值
private BeanExpressionResolver beanExpressionResolver;
//spring属性类型转换
private ConversionService conversionService;
//设置属性注册解析器PropertyEditor 这个主要是对bean的属性等设置管理的一个工具
private final Set<PropertyEditorRegistrar> propertyEditorRegistrars = new LinkedHashSet<>(4);
// 属性注册解析器容器
private final Map<Class<?>, Class<? extends PropertyEditor>> customEditors = new HashMap<>(4);
//类型转换器
private TypeConverter typeConverter;

//方法参数名的解析器策略
private ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
// 将字符串解析器应用于注释属性值
private final List<StringValueResolver> embeddedValueResolvers = new CopyOnWriteArrayList<>();

有了上面的铺垫,我们开始从AnnotationConfigApplicationContext(Class<?>… annotatedClasses)方法中开始讲解

三、BeanFactory方法

public interface BeanFactory {

	//返回以给定名字注册的bean实例。如果没有找到指定的bean,将返回一个新建的实例
	Object getBean(String name) throws BeansException;
	<T> T getBean(String name, Class<T> requiredType) throws BeansException;
	Object getBean(String name, Object... args) throws BeansException;
	<T> T getBean(Class<T> requiredType) throws BeansException;
	<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;

	//返回指定bean的提供程序,允许延迟按需检索实例,包括可用性和唯一性选项。
	<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);
	<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);

	//容器中是否存在查找的bean
	boolean containsBean(String name);
   //是否singleton,如果bean没找到,则抛出NoSuchBeanDefinitionException异常
	boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
   //是否prototype,如果bean没找到,则抛出NoSuchBeanDefinitionException异常
	boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

	//检查具有给定名称的bean是否与指定类型匹配。如果bean没找到,则抛出NoSuchBeanDefinitionException异常
	boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
	boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;

	//获取对应名字bean的类型。如果bean没找到,则抛出NoSuchBeanDefinitionException异常
	Class<?> getType(String name) throws NoSuchBeanDefinitionException;
	//获取别名数组
	String[] getAliases(String name);
}

四、延伸

1、beanFactory和factoryBean的区别

BeanFactory是接口,提供了IOC容器最基本的形式,给具体的IOC容器的实现提供了规范

FactoryBean也是接口,为IOC容器中Bean的注册提供了更加灵活的方式,FactoryBean在IOC容器的基础上给Bean的实现加上了一个简单工厂模式和装饰模式。FactoryBean以Bean结尾,表示它是一个Bean,不同于普通Bean的是:它是实现了FactoryBean接口的Bean,根据该Bean的ID从BeanFactory中获取的实际上是FactoryBean的getObject()返回的对象,而不是FactoryBean本身,如果要获取FactoryBean对象,请在id前面加一个&符号来获取。

public interface FactoryBean<T> {
    ///返回的对象实例
	@Nullable
	T getObject() throws Exception;
    //Bean的类型
	@Nullable
	Class<?> getObjectType();
     
    //bean是否单例
	default boolean isSingleton() {
		return true;
	}

}
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值