Spring注解配置加载解析原理一

本文主要利用AnnotationConfigApplicationContext 注册加载Spring上下文
项目启动:

@Configuration
@ComponentScan(basePackages="com.gz.spring.springbean")
public class SpringBeanConfigutionTest {

    @SuppressWarnings("resource")
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ac = 
                new AnnotationConfigApplicationContext(SpringBeanConfigutionTest.class);
        ac.getBean(SpringBeanTest.class);
        ac.getBean(SpringBeanTest.class);
    }
}

1 创建AnnotationConfigApplicationContext实例对象

代码如下:

public AnnotationConfigApplicationContext(Class... annotatedClasses) {
        this();
        register(annotatedClasses);
        refresh();
    }

在这段代码中主要做了3件事

创建AnnotationConfigApplicationContext实例对象,时序图1.1
注册参数bean到spring上下文中,时序图1.2。
刷新Spring容器,时序图1.3。

时序图如下:

Spring注解配置加载解析原理一_第1张图片

1.1 创建AnnotationConfigApplicationContext实例对象

代码

public AnnotationConfigApplicationContext() {
        // 创建AnnotatedBeanDefinitionReader对象
        this.reader = new AnnotatedBeanDefinitionReader(this);
        // 创建ClassPathBeanDefinitionScanner对象
        this.scanner = new ClassPathBeanDefinitionScanner(this);
}
public class AnnotatedBeanDefinitionReader {
    public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
        this(registry, getOrCreateEnvironment(registry));
    }
    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);
    }
}

Spring注解配置加载解析原理一_第2张图片
分析
创建AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner对象,跟踪代码可知,在实例化AnnotatedBeanDefinitionReader对象是,默认注入了5个实例。

在AnnotatedBeanDefinitionReader实例化时会根据具体情况注入一下类分别是:

// 用户配置Configuration注解,实现了BeanDefinitionRegistryPostProcessor接口
ConfigurationClassPostProcessor
// 用于配置Autowired注解,实现了MergedBeanDefinitionPostProcessor接口
AutowiredAnnotationBeanPostProcessor
// 用于配置Required注解,实现了MergedBeanDefinitionPostProcessor接口
RequiredAnnotationBeanPostProcessor
// 用于配置JSR-250注解,实现了InstantiationAwareBeanPostProcessor接口
CommonAnnotationBeanPostProcessor
// 用于配置JPA注解
PersistenceAnnotationBeanPostProcessor
// 用于配置EventListener注解,实现了SmartInitializingSingleton接口
EventListenerMethodProcessor
// EventListener工厂
DefaultEventListenerFactory

1.2 注册参数bean到spring上下文中

代码

public void register(Class... annotatedClasses) {
        Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
        // 将annotatedClasses注入到spring上下中
        this.reader.register(annotatedClasses);
}

Spring注解配置加载解析原理一_第3张图片
分析
跟踪代码可以看到,在运行完register(annotatedClasses);方法后,BeanFactory会多以个configurationTest属性,该类就是我们启动时传入的参数SpringBeanConfigutionTest.class

1.3 刷新Spring容器

@Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // ⑴.准备刷新的上下文环境
            prepareRefresh();

            // ⑵.初始化BeanFactory
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // ⑶.对BeanFactory进行各种功能填充
            prepareBeanFactory(beanFactory);

            try {
                // ⑷.子类覆盖方法做额外的处理
                postProcessBeanFactory(beanFactory);

                // ⑸.注册,实例化,调用各种BeanFactory处理器
                invokeBeanFactoryPostProcessors(beanFactory);

                // ⑹.注册拦截Bean创建的Bean处理,这里只是注册,真正调用是再拿去Bean的时候
                registerBeanPostProcessors(beanFactory);

                // ⑺.为上下文初始化Message源,即不同语言的消息体,国际化处理
                initMessageSource();

                // ⑻.初始化应用消息广播器,并放到applicationEventMulticaster bean中
                initApplicationEventMulticaster();

                // ⑼.留给子类来初始化其他bean
                onRefresh();

                // ⑽.在所有注册的bean中查找Listener bean,注册到消息广播中
                registerListeners();

                // ⑾.初始化剩下的单实例(非惰性)
                finishBeanFactoryInitialization(beanFactory);

                // ⑿.完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人
                finishRefresh();
            }

            catch (BeansException ex) {
                if (logger.isWarnEnabled()) {
                    logger.warn("Exception encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
                }

                // Destroy already created singletons to avoid dangling resources.
                destroyBeans();

                // Reset 'active' flag.
                cancelRefresh(ex);

                // Propagate exception to caller.
                throw ex;
            }

            finally {
                // Reset common introspection caches in Spring's core, since we
                // might not ever need metadata for singleton beans anymore...
                resetCommonCaches();
            }
        }
    }

分析:

⑴.准备刷新的上下文环境
⑵.初始化BeanFactory
⑶.对BeanFactory进行各种功能填充
⑷.子类覆盖方法做额外的处理
⑸.注册,实例化,调用各种BeanFactory处理器
⑹.注册拦截Bean创建的Bean处理,这里只是注册,真正调用是再拿去Bean的时候
⑺.为上下文初始化Message源,即不同语言的消息体,国际化处理
⑻.初始化应用消息广播器,并放到applicationEventMulticaster bean中
⑼.留给子类来初始化其他bean
⑽.在所有注册的bean中查找Listener bean,注册到消息广播中
⑾.初始化剩下的单实例(非惰性)
⑿.完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人

刷新在父类AbstractBeanFactory中实现,原理详情请看【Spring注解配置加载解析原理二】

你可能感兴趣的:(spring)