天天看点

spring系列——BeanFactory接口系列、IoC容器机制原理

目录

1、IoC容器存储bean的原理:

2、BeanFactory接口的继承关系

BeanFactory是生产bean实例化对象的工厂类,要生产,首先要有呀,所有BeanFactory以及它的各种实现类,其实就是各种实现不同的容器,这些容器可以统称为IoC容器。

容器有各种不同的容器(Factory),容器之间可能就会有继承关系,这个上下级的继承关系就是容器分层,也许父容器有自己的存储bean的结构,子容器也有自己的存储bean的结构。

1、IoC容器存储bean的原理:

资料正规介绍为三个过程:1,用Resource接口找到资源文件。2,将文件中的bean转换为spring需要的BeanDefinition结构。3,将这些BeanDefinition注册(就是存进规定的ConcurrentHashMap结构中)。

下面是通俗的、详细的介绍:

1、用户编定义好bean,此时的bean是用户层面的。

2、启动spring,spring去读取资源、配置等等文件,获取每一个bean的信息,将每一个bean及其相关的信息封装成BeanDefinition类对象(class对象)形式,BeanDefinition形式是spring层面的(spring需要的),然后将这些BeanDefinition对象存储在一个beanDefinitionMap(ConcurrentHashMap结构)中,这叫注册。

3、当用户通过BeanFactory调用getBean()去获取某个bean的实例化对象时,(注意:单例模式的bean有专门的结构存储),如果这个bean是单例模式,就先去SingletonObjects(ConcurrentHashMap结构,专门存储单例模式bean的实例化对象)里面看看是否已经有这个bean的对象,有就返回,没有的话,则去beanDefinitionMap中查找这个bean对应的BeanDefinition,如果没有,则报错,如果有,就根据BeanDefinition里的信息生成一个对象(通过反射机制生成对象),同时还要把这个对象存储到SingletonObjects结构中去(因为这个bean是单例模式),然后返回此对象。如果我们getBean() 要获取的bean是原型模式,那就直接去beanDefinitionMap中去找,如果没有这个bean的BeanDefinition,就报错,如果有,就生成对象并返回对象(不存到SingletonObjects中哦~)。

这就是我们说的IoC容器管理着bean。

问题1,根据BeanDefinition如果生成一个对象呢?用户在定义bean的时候,有两种:一种是构造函数形式、另一个种是property形式,就根据这个,如果是第一种的话,就用构造函数生成对象,如果是第二种的话,运行空构造函数,然后用setter方法完成初始化。默认是第二种。

问题2,java类在xml文件中就反映为bean,类之间的引用关系,在xml中就表现为依赖,那什么时候将依赖注入呢?在bean实例化的时候就注入依赖。什么时候实例化呢?第一,容器初始化的时候,有些bean设置了lazy-init属性为false,意思就是不延迟实例化,即在容器初始化的时候就初始化(初始化就是实例化)这些bean。第二,用户调用getBean()的时候,即要用的时候,才是实例化这些bean。

2、BeanFactory接口的继承关系

spring系列——BeanFactory接口系列、IoC容器机制原理

主要将重点放在BeanFactory 和 ApplicationContext 方向上。 实现类重点在 DefaultListableBeanFactory类。

对于BeanFactory接口的实现有很多,本文只讲比较重要的。

我们常说bean都交给容器管理了,当需要的时候,拿就行了。BeanFactory接口是给用户用的,通过BeanFactory接口的实现类的具体方法,我们可以获取到bean的实例化对象,这就是BeanFactory的主要作用。

BeanFactory接口定义了基本的bean操作:

public interface BeanFactory {
    String FACTORY_BEAN_PREFIX = "&";
    //各种形式的获取bean方法
    Object getBean(String var1) throws BeansException;
    <T> T getBean(String var1, Class<T> var2) throws BeansException;
    Object getBean(String var1, Object... var2) throws BeansException;
    <T> T getBean(Class<T> var1) throws BeansException;
    <T> T getBean(Class<T> var1, Object... var2) throws BeansException;
   
    <T> ObjectProvider<T> getBeanProvider(Class<T> var1);
    <T> ObjectProvider<T> getBeanProvider(ResolvableType var1);
    //容器是否含有指定名字的bean
    boolean containsBean(String var1);
    //指定名字的bean是否是单例模式
    boolean isSingleton(String var1) throws NoSuchBeanDefinitionException;
    //指定名字的bean是否是原型模式
    boolean isPrototype(String var1) throws NoSuchBeanDefinitionException;
    //指定名字的bean是否是var2类型
    boolean isTypeMatch(String var1, ResolvableType var2) throws NoSuchBeanDefinitionException;
    boolean isTypeMatch(String var1, Class<?> var2) throws NoSuchBeanDefinitionException;
    //查询指定名字的class类型
    @Nullable
    Class<?> getType(String var1) throws NoSuchBeanDefinitionException;
    //查询指定名字的bean的所有别名
    String[] getAliases(String var1);
}
           

BeanFactory接口只是入口,有各种实现类,这些实现类都各自有特色功能,比如:XmlBeanFactory类,这个类的内部有一个类叫XmlBeanDefinitionReader,这个Reader类就负责读取xml文件,然后解析xml文件中的信息。

3、 ListableBeanFactory 接口系列

ListableBeanFactory接口源码如下:

继承了BeanFactory接口,同时也定义了自己的方法。代码中的注释,由于一个BeanDefinition对应一个Bean,基本信息是一样的,只是数据结构不同。接口中每个方法定义了基本的操作,但是具体如何实现,还需看具体的实现类,有一个简单的实现类StaticListableBeanFactory类,这个类不重要,不作介绍。

public interface ListableBeanFactory extends BeanFactory {
    //此bean工厂是否包含名字为var1的bean的BeanDefinition
    boolean containsBeanDefinition(String var1); 
    //返回BeanDefinition的个数
    int getBeanDefinitionCount();
    //返回所有BeanDefinition的名字
    String[] getBeanDefinitionNames();
    //返回指定类型的所有的Bean的名字
    String[] getBeanNamesForType(ResolvableType var1);
    String[] getBeanNamesForType(@Nullable Class<?> var1);
    String[] getBeanNamesForType(@Nullable Class<?> var1, boolean var2, boolean var3);
    //返回指定类型的所有Bean
    <T> Map<String, T> getBeansOfType(@Nullable Class<T> var1) throws BeansException;
    <T> Map<String, T> getBeansOfType(@Nullable Class<T> var1, boolean var2, boolean var3) throws BeansException;
    //返回所有带有此注解的bean的名字
    String[] getBeanNamesForAnnotation(Class<? extends Annotation> var1);
    //返回所有带有此注解的bean
    Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> var1) throws BeansException;
    //返回指定bean的注解
    @Nullable
    <A extends Annotation> A findAnnotationOnBean(String var1, Class<A> var2) throws NoSuchBeanDefinitionException;
}
           

4、DefaultListableBeanFactory 类

其它的接口定义,最终都被DefaultListableBeanFactory类实现了,DefaultListableBeanFactory类是spring 默认情况下使用的基本容器,我们就直接看它吧:

下图,我觉得很简单明了,所以贴在这,借用的是:https://www.cnblogs.com/duanxz/p/3787884.html 这篇文章中的一个图。

spring系列——BeanFactory接口系列、IoC容器机制原理