继续介绍AnnotationConfigApplicationContext工作流程,本篇介绍refresh方法,即bean工厂的初始化阶段。读完本篇你会了解到bean是什么时候被全部扫描成BeanDefinition注入到工厂中的。还有一些后置处理器的职责。
打印bean工厂中的bean
编写一个配置类:SpringConfig.java,使用@Configuration注解。在main方法中使用AnnotationConfigApplicationContext启动spring。目前我们并没有注入任何bean,打印一下当前bean工厂中的bean。
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
String[] names = applicationContext.getBeanDefinitionNames();
for(String beanName:names){
System.out.println(beanName);
}
运行打印结果如下:
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
springConfig
可以看到,当前bean工厂中竟然有7个bean,除了配置类SpringConfig是我们注入的以外,其它都是spring自动注入的,而且bean的名称都是包含包名的,这是spring为了避免我们会注入同名的bean所以才使用包名+类名的。那么这些bean是什么时候被注入的呢?以及这些bean的作用是什么呢?带着这两个问题来继续分析refresh方法。
这一堆Processor是什么时候注入的
最好在打印出这些bean的名称的时候也把bean的类型打印出来,我这里直接给出打印的结果。
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.ConfigurationClassPostProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.EventListenerMethodProcessor
org.springframework.context.event.internalEventListenerFactory
org.springframework.context.event.DefaultEventListenerFactory
springConfig
wjy.stu.config.SpringConfig$$EnhancerBySpringCGLIB$$3a397ac0
按实现接口分类:
BeanFactoryPostProcessor:
ConfigurationClassPostProcessor
BeanPostProcessor:
AutowiredAnnotationBeanPostProcessor
RequiredAnnotationBeanPostProcessor
CommonAnnotationBeanPostProcessor
Aware:
EventListenerMethodProcessor
解决问题一:这一堆Processor是什么时候注入的?
可以通过调试手段一步步找出来,最后我在AnnotationConfigApplicationContext的构造方法中,register方法执行之前下断点调试,最终发现这些bean在register方法之前就已经在bean工厂中了。
所以这些bean肯定是在构造方法中注入的,但是在AnnotationConfigApplicationContext方法中以及在其父类构造方法中都没有找到注入这些bean的代码。但是在构造方法中却找到了实例化AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner。register方法最终是调用AnnotatedBeanDefinitionReader实例的register方法完成注册的,所以我猜想这些默认的bean一定是在AnnotatedBeanDefinitionReader的构造方法中注入的。
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
来看下AnnotatedBeanDefinitionReader的构造方法。
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
果不其然,在AnnotatedBeanDefinitionReader的构造方法中调用了AnnotationConfigUtils工具类的registerAnnotationConfigProcessors方法注册了注解配置处理器。来看下这个方法的部分源代码。
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
registerAnnotationConfigProcessors(registry, null);
}
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, Object source) {
......
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<BeanDefinitionHolder>(4);
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
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)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 检查JSR-250支持,如果存在,添加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));
}
// 检查JPA支持,如果存在,添加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;
}
这一堆Processor的作用是什么?
spring为什么要注入这一堆Processor,肯定是有作用的,接下来就是通过读源码自己发现这些处理器bean的作用。前面分析过AnnotationConfigApplicationContext构造方法中register方法的执行流程,并没有发现调用这些处理器的地方,所以我们接着分析AnnotationConfigApplicationContext构造方法中register方法执行完成之后执行的refresh方法。
下面给出refresh方法的完整代码以及注释。
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
prepareRefresh();
// 这里获取到的是DefaultListableBeanFactory,前面说过,GenericApplicationContext的子类都是通过持有一个内部bean工厂管理bean的,这个bean工厂就是DefaultListableBeanFactory。
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 准备好bean工厂,就是配置bean工厂。
prepareBeanFactory(beanFactory);
try {
// 允许在上下文子类中对bean工厂进行后置处理。
postProcessBeanFactory(beanFactory);
// 调用bean工厂的后置处理器。
invokeBeanFactoryPostProcessors(beanFactory);
// 注册拦截bean创建的bean后置处理器。
registerBeanPostProcessors(beanFactory);
// 初始化消息源。
initMessageSource();
// 初始化事件的支持
initApplicationEventMulticaster();
// 初始化其他特殊bean。
onRefresh();
// 注册监听器bean。
registerListeners();
// 实例化所有剩余的(非延迟-init)单例。
finishBeanFactoryInitialization(beanFactory);
// 完成刷新发布相应事件
finishRefresh();
}
catch (BeansException ex) {
// 销毁已经创建的单例。
destroyBeans();
// 重置‘active’标志
cancelRefresh(ex);
throw ex;
}
finally {
// 重置Spring核心中的普通内容缓存,因为我们可能再也不需要单例bean的元数据了。
resetCommonCaches();
}
}
}
在此给大家补充一个点,就是如果我们的bean实现了xxxAware接口,那么这些bean实现的这些接口的方法是在什么时候被调用的。这是在prepareBeanFactory方法中发现的,既然发现了就顺带提一下了。
在prepareBeanFactory方法中发现方法内给bean工厂添加了一个bean后置处理器ApplicationContextAwareProcessor。
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
既然这个ApplicationContextAwareProcessor是一个BeanPostProcessor,那么大家如果看懂前面几篇文章应该知道这个ApplicationContextAwareProcessor是在什么时候被调用的了。BeanPostProcessor会在每个bean实例化之后调用初始化方法之前和之后被调用,ApplicationContextAwareProcessor主要实现了其postProcessBeforeInitialization方法,即在调用初始化方法之前完成一些任务。那么ApplicationContextAwareProcessor的任务又是什么呢?处理调用bean实现了Aware接口的方法。
@Override
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
......
invokeAwareInterfaces(bean);
......
return bean;
}
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof Aware) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
}
其中我们最熟悉的莫过于ApplicationContextAware了,我们为了能在bean中拿到ApplicationContext就是通过实现ApplicationContextAware接口的。
ConfigurationClassPostProcessor
好了,现在接着分析invokeBeanFactoryPostProcessors方法,因为invokeBeanFactoryPostProcessors方法中调用的BeanFactoryPostProcessors,我记得在第一篇分析spring源码的文章中提到过这个BeanFactoryPostProcessors,就是在bean工厂准备好之后调用的处理器。
ConfigurationClassPostProcessor是实现了BeanDefinitionRegistryPostProcessor接口的,而BeanDefinitionRegistryPostProcessor接口又是继承BeanFactoryPostProcessors接口的。
invokeBeanFactoryPostProcessors方法最后调用了PostProcessorRegistrationDelegate委托类的静态方法invokeBeanFactoryPostProcessors方法。来看下这个方法。
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// 如果有则首先调用 BeanDefinitionRegistryPostProcessors ,
// BeanDefinitionRegistryPostProcessors是继承BeanFactoryPostProcessor的接口
Set<String> processedBeans = new HashSet<String>();
//如果bean工厂实现了BeanDefinitionRegistry接口,
//这里的bean工厂就是DefaultListableBeanFactory
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList<BeanDefinitionRegistryPostProcessor>();
// 此时beanFactoryPostProcessors是空的,因为这个方法是在refresh方法中被调用的,而refresh方法之前我们并没有注册任何的BeanFactoryPostProcessor
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
......
}
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
// 首先调用实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessors。
// 获取BeanDefinitionRegistryPostProcessors的bean名称
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
//如果是实现了PriorityOrdered接口的,这个PriorityOrdered接口并没有任何方法的定义,只是用来确定优先级的。
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
//排序这些BeanDefinitionRegistryPostProcessors
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
//开始调用这些BeanDefinitionRegistryPostProcessors
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
..........
}
通过断点调试发现beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false)获取到的就只有ConfigurationClassPostProcessor这个bean。
接着就是看ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)方法了。
看懂这个方法就能知道这个ConfigurationClassPostProcessor的作用是什么了。
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
this.factoriesPostProcessed.add(factoryId);
if (!this.registriesPostProcessed.contains(factoryId)) {
processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
}
enhanceConfigurationClasses(beanFactory);
beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}
/**
* 处理注解配置类注册的class
*/
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
//用于保存所有被@Configuration注解的类,或者有@Bean注释的方法的类
List<BeanDefinitionHolder> configCandidates = new ArrayList<BeanDefinitionHolder>();
//获取当前bean工厂中所有已注册的bean的名称
String[] candidateNames = registry.getBeanDefinitionNames();
for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
//如果这个bean是被@Configuration注释的bean,或者这个bean中有被@Bean方法注释的方法。
if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
......
// 解析每个@Configuration类
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
//使用当前configCandidates构造一个新的集合
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<BeanDefinitionHolder>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<ConfigurationClass>(configCandidates.size());
do {
// candidates中存放的是所有配置类,解析candidates中的配置类。
// 这个方法我们需要重点关注,下面会分析
parser.parse(candidates);
parser.validate();
// parser.getConfigurationClasses()获取当前解析出来(包括在此之前的)的所有的配置类。
Set<ConfigurationClass> configClasses = new LinkedHashSet<ConfigurationClass>(parser.getConfigurationClasses());
// 移除已经解析过的配置类
configClasses.removeAll(alreadyParsed);
// this.reader是一个ConfigurationClassBeanDefinitionReader
this.reader.loadBeanDefinitions(configClasses);
// 将当前配置类设置为已经解析。
alreadyParsed.addAll(configClasses);
//清空当前配置类解析出来的所有bean定义
candidates.clear();
......
//candidates又存放了当前被解析出来的bean定义中有被@Configuration注释的类
}while (!candidates.isEmpty());
......
}
所以配置类中@Import、@ComponentScans以及@Bean注释的方法都是在这里被处理的,如果被@Configuration注释的配置类中使用了@Import导入了其它配置了,那么这个do{}while()就是处理@Import导入的其它配置了的,广度优先遍历直到所有的配置类都已经被处理完成,这样整合spring容器就初始化完成了。我们先继续深入查看ConfigurationClassParser的parse方法。
ConfigurationClassParser的parse方法->
processConfigurationClass方法。
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
throws IOException {
// 先递归地处理任何成员(嵌套)类
processMemberClasses(configClass, sourceClass);
// 处理任何@PropertySource注解
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), PropertySources.class,
org.springframework.context.annotation.PropertySource.class)) {
}
// 处理任何@ComponentScan注解(包括@ComponentScans)
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
}
// 处理@Import注解
processImports(configClass, sourceClass, getImports(sourceClass), true);
// 处理任何@ImportResource注解
if (sourceClass.getMetadata().isAnnotated(ImportResource.class.getName())) {
}
// 处理@Bean注解的方法
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
}
// 处理接口上的默认方法
processInterfaces(configClass, sourceClass);
......
return null;
}
我已经去掉了具体的处理代码,直接给出processConfigurationClass方法处理配置类的内容而已,提供个思路给你自己去看。
好了,到这里已经可以明确直到这个ConfigurationClassPostProcessor处理器的作用了,文章也很长了,所以下面我只介绍剩下几个Processor是在什么时候被调用的,具体这个Processor的作用是什么就靠看观自己去发现了。
registerBeanPostProcessors方法
继续分析refresh方法。在invokeBeanFactoryPostProcessors方法之后就是registerBeanPostProcessors方法。而registerBeanPostProcessors方法最终是调用PostProcessorRegistrationDelegate类的静态方法registerBeanPostProcessors。
所以
AutowiredAnnotationBeanPostProcessor
RequiredAnnotationBeanPostProcessor
CommonAnnotationBeanPostProcessor
是在registerBeanPostProcessors方法中被调用的,在ConfigurationClassPostProcessor被调用完成之后,也就是在处理完所有bean的注册之后调用。这几个处理器可以根据其类型名称猜测其功能,如Autowired处理自动装配。
@by~ 就介绍到这里了,我觉得贴一堆代码出来也没有任何意义,还不如自己直接去看源码呢,所以我只提供个思路,具体更详细的功能实现就需要大伙自己去看源码了。