spring中annotation配置流程解析

176 阅读3分钟

开始

下面是一段使用注解的方式配置,并获取bean对象实例。

public class SpringAnnotationFlowerTest {

    public static void main(String[] args) {
        // 创建ApplicationContext
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        // 注册配置类
        applicationContext.register(PersonConfiguration.class);
        // 刷新ApplicationContext
        applicationContext.refresh();
        // 获取bean对象并使用
        Person p = (Person) applicationContext.getBean("person");
        System.out.println(p);
    }

    @Configuration
    static class PersonConfiguration {

        @Bean("person")
        public Person getPerson() {
            System.out.println("getPerson...");
            return new Person(null, "tom");
        }

    }

}

这里使用到了AnnotationConfigApplicationContext来创建,并将PersonConfiguration.class注册进去,调用refresh来初始化。最终获取bean对象并打印。

创建ApplicationContext

我们先看看AnnotationConfigApplicationContext的构造函数。

public AnnotationConfigApplicationContext() {
	this.reader = new AnnotatedBeanDefinitionReader(this);
	this.scanner = new ClassPathBeanDefinitionScanner(this);
}

这里会实例化两个属性, AnnotatedBeanDefinitionReader读取器用来读取并注册到工厂, ClassPathBeanDefinitionScanner用来扫描Bean的定义。

AnnotatedBeanDefinitionReader的构造方法有个小细节,会注册spring内部几个BeanDefinition。

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
	...
	AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}

主要有如下几个BeanDefinitionRegistryPostProcessor定义:

- ConfigurationClassPostProcessor
- AutowiredAnnotationBeanPostProcessor
- CommonAnnotationBeanPostProcessor
- EventListenerMethodProcessor
- DefaultEventListenerFactory

ConfigurationClassPostProcessor其实就是对应我们的@Configuration注解标识的配置类处理器,实现我们配置类里面的@Bean能被装配到spring中。

注册配置类

当我们将自定义的PersonConfiguration通过applicationContext.register(PersonConfiguration.class);注册。 实际上调用了reader进行注册处理

public void register(Class<?>... annotatedClasses) {
	Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
	this.reader.register(annotatedClasses);
}

一路跟踪调用链,最终调用AnnotatedBeanDefinitionReader里面的doRegister方法中。

<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
			@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {

	AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
	if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
		return;
	}

	abd.setInstanceSupplier(instanceSupplier);
	ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
	abd.setScope(scopeMetadata.getScopeName());
	String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

	AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
	if (qualifiers != null) {
		for (Class<? extends Annotation> qualifier : qualifiers) {
			if (Primary.class == qualifier) {
				abd.setPrimary(true);
			}
			else if (Lazy.class == qualifier) {
				abd.setLazyInit(true);
			}
			else {
				abd.addQualifier(new AutowireCandidateQualifier(qualifier));
			}
		}
	}
	for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
		customizer.customize(abd);
	}

	BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
	definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
	BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}

上面的实现逻辑主要是将PersonConfiguration封装成AnnotatedGenericBeanDefinition,并注册到工厂。

ApplicationContext.refresh

前面的步骤都是在做准备, refresh才是核心。先看下源码:

public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
		// Prepare this context for refreshing.
		prepareRefresh();

		// Tell the subclass to refresh the internal bean factory.
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

		// Prepare the bean factory for use in this context.
		prepareBeanFactory(beanFactory);

		try {
			// Allows post-processing of the bean factory in context subclasses.
			postProcessBeanFactory(beanFactory);

			// Invoke factory processors registered as beans in the context.
			invokeBeanFactoryPostProcessors(beanFactory);

			// Register bean processors that intercept bean creation.
			registerBeanPostProcessors(beanFactory);

			// Initialize message source for this context.
			initMessageSource();

			// Initialize event multicaster for this context.
			initApplicationEventMulticaster();

			// Initialize other special beans in specific context subclasses.
			onRefresh();

			// Check for listener beans and register them.
			registerListeners();

			// Instantiate all remaining (non-lazy-init) singletons.
			finishBeanFactoryInitialization(beanFactory);

			// Last step: publish corresponding event.
			finishRefresh();
		}
    ... //省略异常处理等
}

refresh处理流程如下:

- prepareRefresh() 预处理刷新,主要是记录当前时间,环境。
- obtainFreshBeanFactory() 获取工厂(其实就是DefaultListableBeanFactory)
- prepareBeanFactory() 预处理工厂,配置beanFactory以及忽略一些Aware回调接口
- postProcessBeanFactory() 当前没有实现
- invokeBeanFactoryPostProcessors() 这里是调用我们的BeanFactoryPostProcessors
- registerBeanPostProcessors()注册BeanPostProcessors
- initMessageSource() 初始化消息组件
- initApplicationEventMulticaster() 初始化事件组件
- onRefresh() 空实现
- registerListeners() 注册事件
- finishBeanFactoryInitialization() 完成实例化(主要是将一些非延迟bean提前实例化)
- finishRefresh() 完成刷新

上面的流程比较多,我们主要关注invokeBeanFactoryPostProcessors(beanFactory);以及finishBeanFactoryInitialization(beanFactory);即可。

invokeBeanFactoryPostProcessors(beanFactory)
  1. invokeBeanFactoryPostProcessors会依次调用BeanFactoryPostProcessors后置处理器列表。这其中包含Spring一开始默认添加进去的ConfigurationClassPostProcessor
  2. ConfigurationClassPostProcessor会解析被@Configuration修饰的配置类(就是我们已经注册进去的PersonConfiguration),并将配置类中的BeanDefinition信息注册到BeanFactory。
  3. @Bean被修饰的方法封装成一个BeanDefinition,需要注意的是里面的factoryBean是当前配置类实例,factoryMethod是@Bean修饰的方法(后面是以工厂方法反射的机制来生成实例)
finishBeanFactoryInitialization(beanFactory)
  1. invokeBeanFactoryPostProcessors执行完成后,BeanFactory已经拥有我们在配置类声明的@Bean对象定义信息
  2. 遍历BeanFactory中bean定义信息,并将非延迟初始化singletons作用域的bean调用getBean提前初始化。
  3. 最终在getBean时,通过工厂方法调用的方式,在AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod中以反射的方式调用了我们@Bean声明的方法获取对象并返回。

获取bean对象并使用

由于在refresh阶段已经初始化好了非延迟的bean集合, 所以这里在获取时,直接从缓存中取出并返回给用户使用。