码迷,mamicode.com
首页 > 移动开发 > 详细

spring IOC - AnnotationConfigApplicationContext#this

时间:2020-07-28 00:12:25      阅读:98      评论:0      收藏:0      [点我收藏+]

标签:集成   process   als   amp   接口   except   nts   may   ssl   

前言

目前接触到所有的java框架中, 或多或少, 都需要spring, 有的是基于spring, 有的是需要与spring集成使用. 对于 spring , 就像是大厦的地基. 所以不能不看看这个地基是怎么建的.

以前也时常看 spring 源码, 都是一知半解的, 不知其真解. spring 太过庞大, 想要完全弄懂, 所消耗的时间和精力, 是我负担不起的. 所以对一些主要的地方, 做一些记录和总结.

 

源码版本

我这里下载阅读的是 spring-framework-5.1.12.RELEASE 版本

spring 版本之间是有变动的, 如: 5.1版本开始,  在创建  AnnotatedBeanDefinitionReader 的时候,

干掉了一个后置处理器: REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME --> RequiredAnnotationBeanPostProcessor .

 

说明

对象

bean

BeanDefinition    简称 bd

这三个东西, 我觉得首先要理解一下, 不然看spring源码的时候, 会懵.

1. 首先要明确的是, 只有被 spring 容器托管的对象, 才可以称之为 bean.

    当一个对象在spring中被 new 出来的时候, 他任然不是一个bean. spring任然需要对这个对象进行处理, 比如: 注入, 代理等. 当所有操作都完成后, 放到spring指定的地方, 他才是一个完整的bean

2. bean 肯定是对象, 但是对象不一定是 bean

3. spring 会根据 BeanDefinition 来创建 bean. BeanDefinition 可以理解为 bean 的说明书, 他存放着 bean 的属性和特性, 比如: bean 的颜色, 形状, 创建依赖等等信息.

    从命名上看, BeanDefinition 也是很好理解的. Definition 是定义的意思, 合起来就是 bean 的定义.

 

AnnotationConfigApplicationContext

spring提供了 xml 方式和 Annotation 方式. 这里主要记录 Annotation 方式. 对于 xml 方式, 个人是不喜欢用的. 项目中也是越来越少见了, 所以不管xml方式.

开始代码:

AnnotationConfigApplicationContext acac = new AnnotationConfigApplicationContext(StartConfig.class);

StartConfig可以先不管. 后续会随着代码的阅读, 内容会不断的变化. 暂时就先当成一个空的类, 啥也没干.

@Configuration
public class StartConfig {
}

 进入 new AnnotationConfigApplicationContext (StartConfig.class) 方法, 看里面调用了啥:

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
    this();
    register(componentClasses);
    refresh();
}

1. super()

这里会先进父类的构造方法中执行, 其父类方法比较多, 会从顶层开始往下调用, 其中最重要的是 GenericApplicationContext 中的构造方法:

public GenericApplicationContext() {
    this.beanFactory = new DefaultListableBeanFactory();
}

这里非常重要, 在父类构造方法中, 创建了一个默认的 工厂: DefaultListableBeanFactory

 

1.1 new DefaultListableBeanFactory()

在创建这个类的时候, 也是从顶层构造函数开始, 往下调用, 其中设置了三个忽略注入的接口:

public AbstractAutowireCapableBeanFactory() {
    super();
    ignoreDependencyInterface(BeanNameAware.class);
    ignoreDependencyInterface(BeanFactoryAware.class);
    ignoreDependencyInterface(BeanClassLoaderAware.class);
}

 

2. this()

/**
 * 初始化一个bean的读取器和扫描器
 * 默认构造函数,如果直接调用这个默认构造方法,需要在稍后通过调用其register()去注册配置类(javaconfig),并调用refresh()方法刷新容器,
 * 触发容器对注解Bean的载入、解析和注册过程*/
public AnnotationConfigApplicationContext() {
    /**
     * 创建一个读取注解的Bean定义(BeanDefinition)读取器
     */
    this.reader = new AnnotatedBeanDefinitionReader(this);

    //可以用来扫描包或者类,继而转换成bd
    //但是实际上spring扫描包工作不是这个scanner对象来完成的
    //是spring自己new的一个ClassPathBeanDefinitionScanner
    //这里的scanner仅仅是为了程序员能够在外部调用AnnotationConfigApplicationContext对象的scan方法
    this.scanner = new ClassPathBeanDefinitionScanner(this);
}

 

2.1 AnnotatedBeanDefinitionReader

创建 AnnotatedBeanDefinitionReader 的时候, 通过一番调用周转, 最终会调用

org.springframework.context.annotation.AnnotationConfigUtils#registerAnnotationConfigProcessors 方法

/**
 * 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) {

    DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
    if (beanFactory != null) {
        if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
            //AnnotationAwareOrderComparator主要能解析@Order注解和@Priority
            beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
        }
        if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
            //ContextAnnotationAutowireCandidateResolver提供处理延迟加载的功能
            beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
        }
    }

    Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
    //BeanDefinition的注册,这里很重要,需要理解注册每个bean的类型
    if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        //需要注意的是ConfigurationClassPostProcessor的类型是BeanDefinitionRegistryPostProcessor
        //而 BeanDefinitionRegistryPostProcessor 最终实现BeanFactoryPostProcessor这个接口
        RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        //AutowiredAnnotationBeanPostProcessor 实现了 MergedBeanDefinitionPostProcessor
        //MergedBeanDefinitionPostProcessor 最终实现了 BeanPostProcessor
        RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    //5.1版本时, 这里干掉了一个后置处理器: REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME --> RequiredAnnotationBeanPostProcessor

    // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
    if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
    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));
    }

    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));
    }

    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;
}

这个方法中, 主要是注册 后置处理器

//关键方法, 里面注册了几个非常重要的类
//1.org.springframework.context.annotation.internalConfigurationAnnotationProcessor --> ConfigurationClassPostProcessor 处理@Configuration 注解的
//2.org.springframework.context.annotation.internalAutowiredAnnotationProcessor --> AutowiredAnnotationBeanPostProcessor 处理 @Autowired 注解的
//3.org.springframework.context.annotation.internalCommonAnnotationProcessor --> CommonAnnotationBeanPostProcessor 主要处理@Resource、@PostConstruct和@PreDestroy注解的实现
//4.org.springframework.context.event.internalEventListenerProcessor --> EventListenerMethodProcessor
//5.org.springframework.context.event.internalEventListenerFactory -->DefaultEventListenerFactory

这里的 ConfigurationClassPostProcessor , 尤其重要. 其内部, 主要是处理 @Configuration, @ComponentScan, @Import, @Component 的. 

后面需要对这个类进行详细的解析

 

2.2 scanner 

暂时可以不管

spring IOC - AnnotationConfigApplicationContext#this

标签:集成   process   als   amp   接口   except   nts   may   ssl   

原文地址:https://www.cnblogs.com/elvinle/p/13229071.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!