2.2 spring5源码系列 -- ioc加载的整体流程(一)

276 阅读6分钟

这是我参与8月更文挑战的第10天,活动详情查看:8月更文挑战

之前我们知道了spring ioc的加载过程, 具体如下图. 下面我们就来对照下图, 看看ioc加载的源代码.

 下面在用装修类比, 看看个个组件都是怎么工作的.

 

接下来是源码分析的整体结构图. 对照上面的思路梳理出来的

 

一、源码分析的入口 

通常,我们的入口都是从main方法进入. 这里我们也来定义一个main方法

public class MainStarter {
    public static void main(String[] args) {
        // 第一步: 通过AnnotationConfigApplicationContext读取一个配置类
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainStarter.class );
        context.scan("package name");
        Car car = (Car) context.getBean("car");
        System.out.println(car.getName());
        context.close();
    }
}

 

顺便再来看看还有哪些相关的类

/**
 * 这是一个配置类,
 * 在配置类里面定义了扫描的包路径com.lxl.www.iocbeanlifecicle
 * 这是会将这个包下配置了注解的类扫描到ioc容器里面,成为一个成熟的bean
 */
@Configuration
@ComponentScan(basePackages = {"com.lxl.www.iocbeanlifecicle"})
public class MainConfig {
}

这个类有一个注解@Configuration, 这样这个类会被扫描成bean

还有一个注解@ComponentScan(backPackage = {"com.lxl.www.iocbeanlifecicle"}) 他表示, 请扫描com.lxl.www.iocbeanlifecicle包下所有的类.

com.lxl.www.iocbeanlifecicle 这个包下还有哪些类呢? 我们来看看项目结构

 

 

 这是这个包下完整的项目结构. 

下面会逐渐说明, 每个类的用途

 

二. 最重要的类BeanFactory

我们知道在将一个class加载为bean的过程中BeanFactory是最最重要的, 那么他是何时被加载的呢?

我们来跟踪一下带有一个参数的构造方法AnnotationConfigApplicationContext

    public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
        // 进入构造函数, 首先调用自身的构造方法this();
        // 调用自身的构造方法之前, 要先调用父类的构造方法
        this();
        // retister配置注册类
        register(componentClasses);
        // ioc容器shua新接口--非常重要
        refresh();
    }

这就是AnnotationConfigApplicationContext初始化的时候做的三件事

第一件事: this();  //调用自身的无参构造方法. 同时调用父类的构造方法

第二件事: register(componentClasses); // 调用注册器, 这里会加载两个BeanDefinitionReader和BeanDefinitionScanner. 这两位的角色是什么呢? 可以回忆一下之前的框架图

第三件事: refresh();  // 这是ioc容器刷新, 非常重要. 无论是spring boot还是spring mvc都有这个方法. 这个方法包含了整个spring ioc加载的全生命流程. 也是我们要重点学习的方法

 

下面来看看BeanFactory是何时被加载进来的呢?

在初始化方法的时候调用了自身的无参构造函数, 在调用自身无参构造函数的时候, 同时会调用父类的无参构造函数. 

public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry { 
 ...... 
 } 

父类是GenericApplicationContext, 其无参构造函数就做了一件事

   public GenericApplicationContext() {
        // 构造了一个BeanFactory.
        // 在调用GenericApplicationContext父类构造函数, 为ApplicationContext spring上下文对象初始化beanFactory
        // 为什么初始化的是DefaultListableBeanFactory呢?
        // 我们在看BeanFactory接口的时候发现DefaultListableBeanFactory是最底层的实现, 功能是最全的.
        // 查看
       this.beanFactory = new DefaultListableBeanFactory();
    }    

初始化DefaultListableBeanFactory. 

问题: BeanFactory有很多, 为什么初始化的时候选择DefaultListableBeanFactory呢?

我们来看看DefaultListableBeanFactory的结构. 快捷键option + command + u --> Java Class Diagrams

 

 

 通过观察, 我们发现, DefaultListableBeanFactory实现了各种各样的BeanFactory接口, 同时还是先了BeanDefinitionRegistry接口. 

也就是说, DefaultListableBeanFactory不仅仅有BeanFactory的能力, 同时还有BeanDefinitionRegistry的能力. 它的功能是最全的.

所以, 我们使用的是一个功能非常强大的类Bean工厂类. 

 

AnnotationConfigApplicationContext继承了GenericApplicationContext,

而 GenericApplicationContext 实现了AnnotationConfigRegistry接口.

所以AnnotationConfigApplicationContext有AnnotationConfigRegistry的能力.

 

三. bean定义读取器AnnotatedBeanDefinitionReader

接着上面, 第一步调用的是this(). 也就是AnnotationConfigApplicationContext的无参构造函数. 在这个无参构造函数里一共做了两件事情

    public AnnotationConfigApplicationContext() {
        /**
         * 创建了一个Bean定义的读取器.
         * 完成了spring内部BeanDefinition的注册(主要是后置处理器)
         * 读取了很多spring自定义的配置(主要是后置处理器). 这些类都是spring 的原始类.
         */
        this.reader = new AnnotatedBeanDefinitionReader(this); /**
         * 创建BeanDefinition扫描器
         * 可以用来扫描包或者类, 进而转换为bd
         *
         * Spring默认的扫描包不是这个scanner对象
         * 而是自己new的一个ClassPathBeanDefinitionScanner
         * Spring在执行工程后置处理器ConfigurationClassPostProcessor时, 去扫描包时会new一个ClassPathBeanDefinitionScanner
         *
         * 这里的scanner仅仅是为了程序员可以手动调用AnnotationConfigApplicationContext对象的scan方法
         * 通过调用context.scan("package name");扫描处理配置类
         * 扫描
         */
        this.scanner = new ClassPathBeanDefinitionScanner(this );
    }
  1. 初始化AnnotatedBeanDefinitionReader.

  2. 初始化ClassPathBeanDefinitionScanner

我们先来看看AnnotatedBeanDefinitionReader

 

 

 在这里的描述中, 我们知道BeanDefinitionReader是要去扫描配置或者注解, 如果理解为销售的话, 就是扫描楼盘. 这里面就有我们的潜在用户. 也就是我们需要将其转换为bean的对象. 

那么初始化的时候,AnnotatedBeanDefinitionReader做了什么呢?

重点看这句

    public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
        Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
        Assert.notNull(environment, "Environment must not be null");
        this.registry = registry;
        this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
     // 注册注解类型配置的处理器
       AnnotationConfigUtils.registerAnnotationConfigProcessors( this .registry);
    }

注册注解类型配置的处理器

AnnotationConfigUtils.registerAnnotationConfigProcessors( this .registry);

   /**
     * Register all relevant annotation post processors in the given registry.
     * @param registry the registry to operate on
     * @param source the configuration source element (already extracted)
     * that this registration was triggered from. May be {@code null}.
     * @return a Set of BeanDefinitionHolders, containing all bean definitions
     * that have actually been registered by this call
     */
    public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
            BeanDefinitionRegistry registry, @Nullable Object source) {

        // 获取到beanFactory
        DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
        /**
         * 判断beanFactory中是否有AnnotationAwareOrderComparator和ContextAnnotationAutowireCandidateResolver
         * 没有则添加
         */
        if (beanFactory != null) {
            if (!  (beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
                beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
            }
            if (!  (beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
                beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
            }
        }

        // BeanDefinitionHolder: 为BeanDefinition设置名字和别名
        Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

        // 1. 如果registry中没有ConfigurationClassPostProcessor配置类后置处理器, 就添加一个
        if (! registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
            def.setSource(source);
            // 构建BeanDefinitionHolder, 并添加到beanDefs
            beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
        }

        // 2. 如果rigistry中, 没有AutowiredAnnotationBeanPostProcessor  Autowired注解bean的后置处理器, 则添加一个
        if (! registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
            def.setSource(source);
            // 构建BeanDefinitionHolder, 并添加到beanDefs
            beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
        }

        // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
        // 3. 检查对JSR-250的支持, 如果rigistry中没有CommonAnnotationBeanPostProcessor通用注解后置处理器, 则添加一个
        if (jsr250Present && ! registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
            def.setSource(source);
            // 构建BeanDefinitionHolder, 并添加到beanDefs
            beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
        }

        // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
        // 4. 检查对jpa的支持, 如果不包含internalPersistenceAnnotationProcessor, 持久化注解处理器, 就添加一个
        if (jpaPresent && ! registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME) ) {
            RootBeanDefinition def = new RootBeanDefinition();
            try {
                def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
                        AnnotationConfigUtils.class.getClassLoader()));
            }
            catch (ClassNotFoundException ex) {
                throw new IllegalStateException(
                        "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
            }
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
        }

        // 5. 检查对事件监听的支持, 如果不包含事件监听处理器internalEventListenerProcessor, 就添加一个
        if (! registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
        }

        // 6. 如果不包含事件监听工厂处理器internalEventListenerFactory , 就添加一个
        if (! registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
        }

        return beanDefs;
    }

在这里注册了6个后置处理器.