通过AnnotationConfigApplicationContext的构造方法我们可以看到这里面写了三个方法:
1.this();
2.register(componentClasses);
3.refresh();
下面我们来一一分析这三个方法
首先看this();
这里由于AnnotationConfigApplicationContext继承了GenericApplicationContext这个类,所以要先执行父类的无参构造方法,父类的构造方法比较简单,就是执行了下面代码,意思就是new 了一个默认的bean工厂,记住DefaultListableBeanFactory这个对象,后面要会用到
父类构造方法
this.beanFactory = new DefaultListableBeanFactory();
接下来就执行自己的无参构造方法,可以看下面两行代码
自己的构造方法
/*
*1.实例化一个读取器,负责读取加了注解的类,这里的this指的是spring环境,也就是AnnotationConfigApplicationContext = BeanDefinitionRegistry,因为AnnotationConfigApplicationContext继承了GenericApplicationContext,而GenericApplicationContext
* 又继承了BeanDefinitionRegistry,记住这个地方的继承关系后面看到关系图就不会晕
*/
this.reader = new AnnotatedBeanDefinitionReader(this);
/*
* 2.实例化一个扫描器,扫描ClassPath路径下的包以及包下面的类
* 这个this同上
* 完成扫描工作的不是这里的ClassPathBeanDefinitionScanner对象,是spring在别的地方自己new的一个ClassPathBeanDefinitionScanner
* 这里只是方便我们在外部调用,如果不信的话请继续往下看
*/
this.scanner = new ClassPathBeanDefinitionScanner(this);
点进AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry)构造方法可以看到它又调用了
AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment)的构造方法,里面有个方法很重要
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);下面我们来分析这个方法
/**
* 在给定的注册表中注册所有相关的注释后处理器,空壳方法,大概率使用的是委派模式
* @param registry spring注册表,也就是AnnotationConfigApplicationContext
*/
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
registerAnnotationConfigProcessors(registry, null);
}
/*
* 在给定的注册表中注册所有相关的注释后处理器.
* @param registry 要运行的注册表
* @param source the configuration source element (already extracted)
* that this registration was triggered from. May be {@code null}.
* @return a Set of BeanDefinitionHolders, containing all bean definitions
* that have actually been registered by this call
* 注册spring环境bean工厂里面需要的后置处理器
*/
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) {
//1.获取bean工厂
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
//2.如果bean工厂不为空
if (beanFactory != null) {
//3.如果bean工厂里面的dependencyComparator不是AnnotationAwareOrderComparator这个类型的,就把这个属性实例化并设置进去
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
//4.AnnotationAwareOrderComparator.INSTANCE这个实际上是在AnnotationAwareOrderComparator这个类里new了一个
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
//4.如果bean工厂里面的autowireCandidateResolver不是ContextAnnotationAutowireCandidateResolver这个类型的,就把这个属性实例化并设置进去
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
//5.实例化一个ContextAnnotationAutowireCandidateResolver对象
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
//6.定义一个存放BeanDefinitionHolder的Set集合,BeanDefinitionHolder存放的是beanName(bean名称)和beanDefinition(bean定义)以及aliases(别名)
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
/*
* 7.判断registry(实际上是AnnotationConfigApplicationContext)中是否包含beanName = org.springframework.context.annotation.internalConfigurationAnnotationProcessor
* 的beanDefinition,点进去其实就是调用两个方法来判断beanDefinitionMap这个map里面有没有这个beanName和beanDefinition,一个是getBeanFactory(),一个是containsBeanDefinition(String beanName)
* 容器初始化阶段是没有这些beanDefinition的,所以返回false,于是就调用BeanDefinition的实现类RootBeanDefinition的构造方法,传入一个类.class,这也是把一个类转成beanDefinition的一种方式
*/
CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME = "org.springframework.context.annotation.internalConfigurationAnnotationProcessor";
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
//把ConfigurationClassPostProcessor这个类转成beanDefinition,这个类的作用后面会说
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
//把registerPostProcessor()方法返回的BeanDefinitionHolder添加到beanDefs中
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
/*
* 9.判断registry(实际上是AnnotationConfigApplicationContext)中是否包含beanName = org.springframework.context.annotation.internalAutowiredAnnotationProcessor
* 的beanDefinition,点进去其实就是调用两个方法来判断beanDefinitionMap这个map里面有没有这个beanName和beanDefinition,一个是getBeanFactory(),一个是containsBeanDefinition(String beanName)
* 容器初始化阶段是没有这些beanDefinition的,所以返回false,于是就调用BeanDefinition的实现类RootBeanDefinition的构造方法,传入一个类.class,这也是把一个类转成beanDefinition的一种方式
*/
AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME = "org.springframework.context.annotation.internalAutowiredAnnotationProcessor";
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
//把AutowiredAnnotationBeanPostProcessor这个类转成beanDefinition,这个类的作用后面会说
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
//把registerPostProcessor()方法返回的BeanDefinitionHolder添加到beanDefs中
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
/*
10.检查是否支持JSR-250,并且判断registry(实际上是AnnotationConfigApplicationContext)中是否包含beanName = org.springframework.context.annotation.internalCommonAnnotationProcessor
的beanDefinition,点进去其实就是调用两个方法来判断beanDefinitionMap这个map里面有没有这个beanName和beanDefinition,一个是getBeanFactory(),一个是containsBeanDefinition(String beanName)
容器初始化阶段是没有这些beanDefinition的,所以返回false,于是就调用BeanDefinition的实现类RootBeanDefinition的构造方法,传入一个类.class,这也是把一个类转成beanDefinition的一种方式
*/
COMMON_ANNOTATION_PROCESSOR_BEAN_NAME =
"org.springframework.context.annotation.internalCommonAnnotationProcessor";
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
//把CommonAnnotationBeanPostProcessor这个类转成beanDefinition,这个类的作用后面会说
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
//把registerPostProcessor()方法返回的BeanDefinitionHolder添加到beanDefs中
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
/*
* 11.检查是否支持JPA,并且判断registry(实际上是AnnotationConfigApplicationContext)中是否包含beanName = org.springframework.context.annotation.internalPersistenceAnnotationProcessor
* 的beanDefinition,点进去其实就是调用两个方法来判断beanDefinitionMap这个map里面有没有这个beanName和beanDefinition,一个是getBeanFactory(),一个是containsBeanDefinition(String beanName)
* 容器初始化阶段是没有这些beanDefinition的,所以返回false,于是就调用BeanDefinition的实现类RootBeanDefinition的构造方法,传入一个类.class,这也是把一个类转成beanDefinition的一种方式
*/
PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME =
"org.springframework.context.annotation.internalPersistenceAnnotationProcessor";
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);
//把registerPostProcessor()方法返回的BeanDefinitionHolder添加到beanDefs中
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
/*
* 12.判断registry(实际上是AnnotationConfigApplicationContext)中是否包含beanName = org.springframework.context.event.internalEventListenerProcessor
* 的beanDefinition,点进去其实就是调用两个方法来判断beanDefinitionMap这个map里面有没有这个beanName和beanDefinition,一个是getBeanFactory(),一个是containsBeanDefinition(String beanName)
* 容器初始化阶段是没有这些beanDefinition的,所以返回false,于是就调用BeanDefinition的实现类RootBeanDefinition的构造方法,传入一个类.class,这也是把一个类转成beanDefinition的一种方式
*/
EVENT_LISTENER_PROCESSOR_BEAN_NAME =
"org.springframework.context.event.internalEventListenerProcessor";
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
//把EventListenerMethodProcessor这个类转成beanDefinition,这个类的作用后面会说
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
//把registerPostProcessor()方法返回的BeanDefinitionHolder添加到beanDefs中
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
/*
* 13.判断registry(实际上是AnnotationConfigApplicationContext)中是否包含beanName = org.springframework.context.event.internalEventListenerFactory
* 的beanDefinition,点进去其实就是调用两个方法来判断beanDefinitionMap这个map里面有没有这个beanName和beanDefinition,一个是getBeanFactory(),一个是containsBeanDefinition(String beanName)
* 容器初始化阶段是没有这些beanDefinition的,所以返回false,于是就调用BeanDefinition的实现类RootBeanDefinition的构造方法,传入一个类.class,这也是把一个类转成beanDefinition的一种方式
*/
EVENT_LISTENER_FACTORY_BEAN_NAME =
"org.springframework.context.event.internalEventListenerFactory";
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
//把DefaultEventListenerFactory这个类转成beanDefinition,这个类的作用后面会说
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
//把registerPostProcessor()方法返回的BeanDefinitionHolder添加到beanDefs中
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}
return beanDefs;
}
registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)这个方法实现的是把
以上代码主要做了以下几件事情:
1.获取一个DefaultListableBeanFactory;
2.为DefaultListableBeanFactory工厂里面的属性dependencyComparator设置值
3.为DefaultListableBeanFactory工厂里面的属性autowireCandidateResolver重新设置值
4.定义存放BeanDefinitionHolder的集合
5.往DefaultListableBeanFactory工厂里面的beanDefinitionMap添加元素
6.往集合中添加BeanDefinitionHolder
把5拆开来说,看下面这段代码:
registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)
registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)
registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)
registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME)
registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME)
/*
* 根据beanName和beanDefinition转成BeanDefinitionHolder
* @param registry:spring环境(AnnotationConfigApplicationContext)
* @param definition:beanDefinition(bean的一些定义信息)
* @param beanName:bean名称
* @return:BeanDefinitionHolder
*/
private static BeanDefinitionHolder registerPostProcessor(BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
//1.设置角色,ROLE_INFRASTRUCTURE = 2,表示是spring内部的,与用户定义的bean无关
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
//2.把bean和beanDefinition注册到bean工厂里,最终执行的是map.put(beanName,beanDefinition)操作
registry.registerBeanDefinition(beanName, definition);
//3.调用构造方法
return new BeanDefinitionHolder(definition, beanName);
}
上面就是往map里put了五个对象,它们对应的类分别为:
ConfigurationClassPostProcessor
AutowiredAnnotationBeanPostProcessor
CommonAnnotationBeanPostProcessor
EventListenerMethodProcessor
DefaultEventListenerFactory
重点关注ConfigurationClassPostProcessor这个类,后面会用到
然后看第二个方法:register(componentClasses);看这个名字有没有一种上头的感觉,翻译过来不就是注册组件类吗?也确实是这样,这个方法能把我们的java config配置类转成beanDefinition,然后放到一个map里
让我们一步一步往里点
/*
* 注册一个或多个要处理的组件类.
* @param componentClasses 一个或多个组件类,
*/
@Override
public void register(Class<?>... componentClasses) {
Assert.notEmpty(componentClasses, "At least one component class must be specified");
this.reader.register(componentClasses);
}
不要慌,这是一个空壳方法,后面还有很多这样的,再点,进入正题
/*
* 注册一个或多个要处理的组件类
* @param componentClasses 一个或多个组件类
*/
public void register(Class<?>... componentClasses) {
//循环注册组件类
for (Class<?> componentClass : componentClasses) {
registerBean(componentClass);
}
}
因为这里我的项目里只写了一个java config配置类,所以只会循环一次,再往下点
/*
* 从给定的bean类中注册一个bean,从中获取其元数据
* @param beanClass 注册类
*/
public void registerBean(Class<?> beanClass) {
//执行注册bean
doRegisterBean(beanClass, null, null, null, null);
}
我服,还没真正干活,看到do开头方法没,这个就是了,再点下去
/*
* 真正干活的方法
* @param beanClass:java config 配置类
* @param name:null
* @param qualifiers:null
* @param supplier:null
* @param customizers:null
* @param <T>
*/
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {
//1.把传入的bean.class转换成beanDefinition
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
//2.判断这个类是否需要跳过解析,通过代码可以知道spring判断是否跳过解析,主要判断类有没有加注解
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
//3.暂时不知道干啥
abd.setInstanceSupplier(supplier);
//4.得到类的作用域,scopeMetadata(scopeName=singleton,scopedProxyMode=NO)
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
//5.设置类的作用域
abd.setScope(scopeMetadata.getScopeName());
//6.使用beanName生成器生成一个beanName
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
//7.处理类当中的通用注解,分析源码可以知道它主要处理,Lazy DependsOn Primary Role等等注解,处理完成之后 processCommonDefinitionAnnotations中依然是把他添加到数据结构当中,由于我写的配置类都没加,所以不用管
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
/*
* 8.如果在向容器注册注解Bean定义时,使用了额外的限定符注解则解析
* Qualifier和Primary,主要涉及到spring的自动装配
* 这里需要注意的byName和qualifiers这个变量是Annotation类型的数组,里面存不仅仅是Qualifier注解
* 理论上里面里面存的是一切注解,所以可以看到下面的代码spring去循环了这个数组
* 然后依次判断了注解当中是否包含了Primary,是否包含了Lazy
*/
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));
}
}
}
if (customizers != null) {
for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(abd);
}
}
//9.new一个BeanDefinitionHolder
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
//10.需要结合web
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
/*
* 11.把上述的这个数据结构注册给registry,registy就是AnnotationConfigApplicationContext
* AnnotationConfigApplicationContext在初始化的时候通过调用父类的构造方法实例化了一个DefaultListableBeanFactory
* registerBeanDefinition这个方法就是把definitionHolder这个数据结构包含的信息注册到DefaultListableBeanFactory这个工厂
*/
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
通过上面代码注释以及源码分析,我们应该总结以下几点:
1.BeanDefinition是什么?
BeanDefinition是spring定义我们的bean信息所创建的一个类,里面包含lazyInit、Scope、dependsOn等等,就好比在java里我们需要使用Person类定义人一样
2.BeanDefinitionHolder是什么?
它里面存放了beanName和beanDefinition,你可以理解为封装了两个属性,主要为后面方法传参方便
3.在spring中怎么把一个类转成BeanDefinition?
可以new xxBeanDefinition(传入要转换的类);
4.在spring中怎么把把beanDefinition转成BeanDefinitionHolder?
可以new BeanDefinitionHolder(beanDefinition,beanName);
5.spring最终把我们的beanDefinition和beanName放入map中调用的哪个方法?
通过这个registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
可以通过上面注释11点进去就能看到,因为比较简单,就不贴代码了
最后来分析第三个方法:refresh()
@Override
public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {
/*
* 1.这个方法主要做了以下几件事:
* (1).记录容器的启动时间,并将容器状态更改为激活
* (2).调用initPropertySources()方法,主要用于web环境下初始化封装相关的web资源,比如将servletContext封装成为ServletContextPropertySource
* (3).校验环境中必要的属性是否存在
* (4).提供了一个扩展点可以提前放入一些事件,当applicationEventMulticaster这个bean被注册到容器中后就直接发布事件
*/
prepareRefresh();
//2.实际上获取的就是一个DefaultListableBeanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//3.为bean工厂设置一些属性
prepareBeanFactory(beanFactory);
try {
//4.提供给子类复写的方法,允许子类在这一步对beanFactory做一些后置处理
postProcessBeanFactory(beanFactory);
//4.这个方法其实就是把我们的配置类扫描解析,然后把加了注解的类注册到spring bean工厂中
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();
}
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();
}
}
}
这里只需关注前四个方法,毕竟还没到实例化bean的阶段嘛
好了,言归正传,通过注释也能看出哪些方法重要吧
我们就看看prepareBeanFactory(beanFactory)和invokeBeanFactoryPostProcessors(beanFactory)这两个方法
首先来看prepareBeanFactory(beanFactory)这个
/*
* 配置bean工厂
* @param beanFactory:工厂
*/
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
//1.设置classLoader,一般就是appClassLoader
beanFactory.setBeanClassLoader(getClassLoader());
//2.设置el表达式解析器
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
//3.容器中添加一个属性编辑器注册表
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
//4.添加了一个bean的后置处理器,用于执行xxxAware方法
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//5.对以下类型的依赖,不进行依赖检查,不进行依赖检查也就不会进行自动注入
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
/*
* 6.为什么我们能直接将ApplicationContext等一些对象直接注入到bean中呢?就是下面这段代码的作用啦!
* Spring在进行属性注入时会从resolvableDependencies的map中查找是否有对应类型的bean存在,如果有的话就直接注入,下面这段代码就是将对应的bean放入到resolvableDependencies这个map中
*/
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
//7.添加一个后置处理器,用于处理ApplicationListener
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
//8.是否配置了loadTimeWeaver,也就是在类加载时期进行织入,一般都不会配置
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
//加载时期织入会配置一个临时的类加载器
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
//配置一些默认的环境相关的bean
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
也没啥好说的,写了注释,看看第二个方法invokeBeanFactoryPostProcessors(beanFactory)
/*
* 实例化并调用所有已注册的BeanFactoryPostProcessor Bean,*遵循显式顺序(如果给定的话)。 * <p>必须在单例实例化之前调用.
*/
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
需要注意的是getBeanFactoryPostProcessors()这个方法是获取用户自定义的BeanFactoryPostProcessor,自定义分为以下两种:
一.用户写了一个类实现了BeanFactoryPostProcessor或者 BeanDefinitionRegistryPostProcessor接口,加了@Configuration注解;
二.用户写了一个类实现了BeanFactoryPostProcessor或者BeanDefinitionRegistryPostProcessor接口,没加@Configuration注解;
这里自定义指的是第二种,但是需要在AnnotationConfigApplicationContext调用refresh()方法之前,添加这个后置处理器(也就是我们自己写的MyBeanFactoryPostProcessor),调用方法如下:
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
ac.addBeanFactoryPostProcessor(new MyBeanFactoryPostProcessor()),这样传过来的集合才会有值
接下来看PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors())这个方法
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
//创建一个Set集合
Set<String> processedBeans = new HashSet<>();
//判断beanFactory是不是BeanDefinitionRegistry这个类型,因为DefaultListableBeanFactory实现了BeanDefinitionRegistry接口
if (beanFactory instanceof BeanDefinitionRegistry) {
//如果是,就把它转成BeanDefinitionRegistry
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
//创建一个存放我们自定义的BeanFactoryPostProcessor类型的集合
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
//创建一个存放我们自定义BeanDefinitionRegistryPostProcessor类型的集合
//但是后面会和存放spring定义的合并
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
/*
* 循环传过来的beanFactoryPostProcessors,需要注意的是,这里传过来的是用户自定义的BeanFactoryPostProcessor,自定义分为以下两种:
* 一.用户写了一个类实现了BeanFactoryPostProcessor或者 BeanDefinitionRegistryPostProcessor接口,加了@Configuration注解;
* 二.用户写了一个类实现了BeanFactoryPostProcessor或者BeanDefinitionRegistryPostProcessor接口,没加@Configuration注解;
* 这里自定义指的是第二种,但是需要在AnnotationConfigApplicationContext调用refresh()方法之前,添加这个后置处理器(也就是我们自己写的MyBeanFactoryPostProcessor),调用方法如下
* ac.addBeanFactoryPostProcessor(new MyBeanFactoryPostProcessor()),这样传过来的集合才会有值
*/
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
//判断这个postProcessor是不是BeanDefinitionRegistryPostProcessor这个类型,一般看用户写的实现哪个接口就是哪种类型
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
} else {
regularPostProcessors.add(postProcessor);
}
}
/*
* 不要在这里初始化FactoryBeans:我们需要保留所有未初始化的常规bean,以便让bean工厂后处理器对其应用,将实现
* PriorityOrdered,Ordered和其余的BeanDefinitionRegistryPostProcessor分开,
* 这个currentRegistryProcessors 放的是spring内部自己实现了BeanDefinitionRegistryPostProcessor接口的对象
*/
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
/*
* 首先,调用实现PriorityOrdered的BeanDefinitionRegistryPostProcessors,
* getBeanNamesForType 根据bean的类型获取bean的名字ConfigurationClassPostProcessor
* 这个地方可以得到一个BeanFactoryPostProcessor,因为是spring默认在最开始自己注册的,为什么要在最开始注册这个呢?
* 因为spring的工厂需要去解析扫描等功能,而这些功能都是需要在spring工厂初始化完成之前执行
* 要么在工厂最开始的时候、要么在工厂初始化之中,反正不能再之后,因为如果在之后就没有意义,因为那个时候已经需要使用工厂了
* 所以这里spring在一开始就注册了一个BeanFactoryPostProcessor,用来插手springfactory的实例化过程
* 在这个地方断点可以知道这个类叫做ConfigurationClassPostProcessor
* ConfigurationClassPostProcessor那么这个类能干嘛呢?可以参考源码
*/
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
//排序,里面只有一个ConfigurationClassPostProcessor,所以不用管排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
//合并集合
registryProcessors.addAll(currentRegistryProcessors);
//这一步点进去,可以看到执行的是ConfigurationClassPostProcessor中的方法,做一些操作(重要)
//这个地方对配置类进行解析并且完成扫描的入口
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
/*-----------------------------------------------------------------------------------------------------------------------*/
//因为是临时变量,所有要清理掉
currentRegistryProcessors.clear();
//同上面98行操作,根据类型获取spring环境中的beanName集合
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
//循环这个集合
for (String ppName : postProcessorNames) {
//判断processedBeans这个集合中包不包含这个名字并且这个类有没有实现Ordered接口
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
//上面都为true才添加到currentRegistryProcessors集合中
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//把beanName添加到processedBeans集合中
processedBeans.add(ppName);
}
}
//对集合中的元素进行排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
//合并
registryProcessors.addAll(currentRegistryProcessors);
//执行和上面一样的方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//清除集合
currentRegistryProcessors.clear();
//调用所有其他BeanDefinitionRegistryPostProcessor,直到不再出现
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
//处理registryProcessors这个集合中存放我们自定义的BeanDefinitionRegistryPostProcessor,它实现了BeanFactoryPostProcessor接口,所有要执行父类的方法
//BeanDefinitionRegistryPostProcessor
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
//BeanFactoryPostProcessor
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
} else {
//一般不会走到else,因为不会自定义bean工厂
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
} else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
} else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
beanFactory.clearMetadataCache();
}
先看看这张图
分析其中的方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
第一步
/**
* Invoke the given BeanDefinitionRegistryPostProcessor beans.
*/
private static void invokeBeanDefinitionRegistryPostProcessors(Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
//postProcessor == ConfigurationClassPostProcessor,postProcessBeanDefinitionRegistry()
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
}
第二步
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
//1.生成一个注册表ID
int registryId = System.identityHashCode(registry);
if (this.registriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
}
if (this.factoriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + registry);
}
//2.设置注册表ID,表明这个工厂已经经过了后置处理器
this.registriesPostProcessed.add(registryId);
//3.对配置类的beanDefinition进行处理
processConfigBeanDefinitions(registry);
}