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

xiaoxiao2021-02-28  47

本文主要利用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。

时序图如下:

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

分析 创建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); }

分析 跟踪代码可以看到,在运行完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注解配置加载解析原理二】

转载请注明原文地址: https://www.6miu.com/read-2624400.html

最新回复(0)