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