基于最新Spring 5.x,详细介绍了prepareBeanFactory配置BeanFactory、invokeBeanFactoryPostProcessors回调BeanFactoryPostProcessor扩展点、registerBeanPostProcessors注册BeanPostProcessor扩展点。
上一篇文章:Spring IoC容器初始化源码(4)—<context:component-scan/>标签解析、spring.components扩展点、自定义Spring命名空间扩展点中,我们主要讲解了自定义命名空间和Spring5的spring.components这两个容器扩展点,以及< context:component-scan/>扩展标签的解析。
现在我们继续向下学习refresh()方法,到此obtainFreshBeanFactory方法的大概内容算是结束了,我继续向下走,本篇文章的内容主要就是prepareBeanFactory配置BeanFactory、postProcessBeanFactory扩展BeanFactory、invokeBeanFactoryPostProcessors回调BeanFactoryPostProcessor扩展点、registerBeanPostProcessors注册BeanPostProcessor扩展点,以及MessageSource和Listener相关初始化。
Spring IoC容器初始化源码(1)—setConfigLocations设置容器配置信息
Spring IoC容器初始化源码(2)—prepareRefresh准备刷新、obtainFreshBeanFactory加载XML资源、解析<beans/>标签
Spring IoC容器初始化源码(3)—parseDefaultElement、parseCustomElement解析默认、扩展标签,registerBeanDefinition注册Bean定义
Spring IoC容器初始化源码(4)—<context:component-scan/>标签解析、spring.components扩展点、自定义Spring命名空间扩展点
Spring IoC容器初始化源码(5)—prepareBeanFactory、invokeBeanFactoryPostProcessors、registerBeanPostProcessors方法
Spring IoC容器初始化源码(6)—finishBeanFactoryInitialization实例化Bean的整体流程以及某些扩展点
Spring IoC容器初始化源码(7)—createBean实例化Bean的整体流程以及构造器自动注入
Spring IoC容器初始化源码(8)—populateBean、initializeBean实例化Bean以及其他依赖注入
< context:property-placeholder/>标签以及PropertySourcesPlaceholderConfigurer占位符解析器源码深度解析
三万字的ConfigurationClassPostProcessor配置类后处理器源码深度解析
基于JavaConfig的AnnotationConfigApplicationContext IoC容器初始化源码分析
在obtainFreshBeanFactory方法获取到新的BeanFactory之后,随即调用prepareBeanFactory方法对新获取的BeanFactory进行一系列配置。这也是applicationContext功能的扩展。
配置的信息包括:
//------AbstractApplicationContext的相关属性
/**
* 类加载器,用于后面根据className创建bean的实例(如有必要)
*/
@Nullable
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
/**
* bean定义中SPEL表达式的解析器
*/
@Nullable
private BeanExpressionResolver beanExpressionResolver;
/**
* 自定义的属性编辑器注册表
*/
private final Set<PropertyEditorRegistrar> propertyEditorRegistrars = new LinkedHashSet<>(4);
/**
* 按添加顺序先后排列的要使用BeanPostProcessor列表
*/
private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();
/**
* 要忽略自动注入的类型的列表
*/
private final Set<Class<?>> ignoredDependencyInterfaces = new HashSet<>();
/**
* 从依赖项类型映射到相应的自动注入的实例的map
*/
private final Map<Class<?>, Object> resolvableDependencies = new ConcurrentHashMap<>(16);
//---------ConfigurableApplicationContext接口的相关常量属性
/**
* 工厂中的 LoadTimeWeaver bean的名称。
*/
String LOAD_TIME_WEAVER_BEAN_NAME = "loadTimeWeaver";
/**
* 工厂中的 environment bean的名称。
*
* @since 3.1
*/
String ENVIRONMENT_BEAN_NAME = "environment";
/**
* 工厂中的 systemProperties bean的名称。
* java.lang.System#getProperties()可以获取
*/
String SYSTEM_PROPERTIES_BEAN_NAME = "systemProperties";
/**
* 工厂中的 systemEnvironment bean的名称。
* java.lang.System#getenv()可以获取
*/
String SYSTEM_ENVIRONMENT_BEAN_NAME = "systemEnvironment";
/**
* AbstractApplicationContext的方法
*
* 配置工厂的标准上下文特征,例如上下文的 ClassLoader、一些BeanPostProcessor后处理器、手动注册一些的bean等等。
* 这些特征都可以算作applicationContext功能的扩展
*
* @param beanFactory 要配置的BeanFactory
*/
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
/*
* 1 设置BeanFactory的类加载器,用于后面创建bean的实例
* 直接使用上下文容器的类加载器,默认就是 Launcher$AppClassLoader 类加载器实例
*/
beanFactory.setBeanClassLoader(getClassLoader());
/*
* 2 设置SPEL表达式的解析器实例StandardBeanExpressionResolver
* 我们此前学习SPEL表达式的时候就说过,Spring默认使用StandardBeanExpressionResolver解析SPEL表达式#{}
*/
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
/*
* 3 添加一个默认属性编辑器注册表实例ResourceEditorRegistrar
* 主要目的是调用其内部的registerCustomEditors方法注册一批常用的PropertyEditor,比如ResourceEditor
*
* PropertyEditor(属性编辑器)用于bean的属性注入时的类型自动转换,比如value字符串转换为各种集合,Resource资源类型等等
* 我们可以实现PropertyEditorSupport接口自定义属性编辑器
*/
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
/*
* 4 添加一个BeanPostProcessor实例ApplicationContextAwareProcessor
* BeanPostProcessor也是一个扩展回调接口,它的postProcessBeforeInitialization方法在bean的init-method执行之前执行
* 它的postProcessAfterInitialization方法在bean的init-method执行之后执行
*
* ApplicationContextAwareProcessor的目的很简单,如果我们的bean实现了Aware标志性接口下的
* EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware六个接口
* 那么在bean被初始化之后,init-method执行,将会由ApplicationContextAwareProcessor帮助我们调用相关接口的setter方法注入applicationContext或者embeddedValueResolver属性
*/
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
/*
* 5 忽略一批Aware接口的setter方法的自动装配
*
* 这一批接口就上面ApplicationContextAwareProcessor处理的手动装配的接口,由于上面的手动配装,因此不需要自动注入功能
* 在此前的createBeanFactory方法中,就已经忽略了BeanNameAware、BeanFactoryAware、BeanClassLoaderAware接口的setter方法自动装配
*/
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 注册一批指定类型接口的默认自动注入实例
*
* 什么意思呢?一般我们的自动装配,都需要相关的注解、或者XML的配置自动注入
*
* 如果一个接口有多个实现,那么使用自动注入可能会报错
* 使用该方法指定某个类型的接口,如果外部要注入该类型接口的对象,则会直接注入我们指定的对象
*
* BeanFactory、 -> 实际注入的是DefaultListableBeanFactory实例
* ResourceLoader、ApplicationEventPublisher、ApplicationContext ->实际注入的是当前上下文容器实例
*/
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
/*
* 7 添加一个早期的后置处理器实例 ApplicationListenerDetector
*
* ApplicationListenerDetector是一个监听器探测器,专门用来探测监听器
* 在bean实例化和依赖注入完毕之后,用于检测当前bean是不是ApplicationListener监听器的实现,是的话将它注册到应用的事件多播器上。
*/
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
/*
* 8 如果工厂中具有名为loadTimeWeaver名称的bean,则会注册一个LoadTimeWeaverAwareProcessor后置处理器到容器中
*
* 说实话没研究过,看文章是啥类加载期织入AspectJ用的
*/
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
//指定用于类型匹配的临时类加载器。 默认值为无,只需使用标准 bean 类加载器即可。
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
/*
* 9 手动注册一系列系统和JVM环境bean以及实例:
* environment -> 容器环境变量对象,内部包含了systemEnvironment和systemProperties
* systemProperties -> JVM环境变量对象,最开始的setConfigLocations部分我们就见过了
* systemEnvironment -> 系统环境变量对象,最开始的setConfigLocations方法部分我们就见过了
*
* 调用registerSingleton,就是所谓的手动注册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());
}
}
BeanPostProcessor是Spring提供的一个扩展接口,Spring中大部分功能都是通过后处理器的方式进行扩展的。这也是ApplicationContext容器相比于BeanFactory的改进,使用BeanFactory时,BeanPostProcessor需要手动调用方法注册,而使用ApplicationContext时,BeanPostProcessor可以通过< bean/>标签自动注册。
它提供了两个方法,Spring5之后由抽象方法改为默认方法:
/**
* Spring提供的扩展接口
*/
public interface BeanPostProcessor {
/**
* bean实例化以及依赖注入完毕之后,initMethod方法调用完毕之前调用
*
* @param bean 初始化的bean实例
* @param beanName beanName
* @return 后续要使用的 bean 实例,如果为null,则不会调用后续的后置处理器对应的方法,一般还是返回bean
*/
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
//默认返回bean
return bean;
}
/**
*bean实例化以及依赖注入完毕之后,initMethod方法啊调用完毕之后调用
*
* @param bean 初始化的bean实例
* @param beanName beanName
* @return 后续要使用的 bean 实例,如果为null,则不会调用后续的后置处理器对应的方法,一般还是返回bean
*/
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
//默认返回bean
return bean;
}
}
我们只需要实现BeanPostProcessor接口然后将其当作普通bean注册到Spring容器中,在bean实例化的过程中就会自动顺序调用所有BeanPostProcessor实例的相关回调方法。如果要指定顺序,那么增加实现org.springframework.core.Ordered接口即可。
测试类:
public class BeanPostProcessorTest {
private String string;
public BeanPostProcessorTest() {
System.out.println("无参构造器调用");
}
public BeanPostProcessorTest(String string) {
System.out.println("带参构造器调用");
this.string = string;
}
public void setString(String string) {
System.out.println("setter调用");
this.string = string;
}
public void init(){
System.out.println("+++++++++++++++ init-method +++++++++++++++++++");
}
@Override
public String toString() {
return "BeanPostProcessorTest{" +
"string='" + string + '\'' +
'}';
}
}
自定义的后置处理器:
public class MyBeanPostProcessor {
public static class MyBeanPostProcessor1 implements BeanPostProcessor, Ordered {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("-------------postProcessBeforeInitialization1 start-------------");
System.out.println("bean: " + bean);
System.out.println("beanName: " + beanName);
//如果返回null,则不会调用后续的后置处理器对应的方法
System.out.println("-------------postProcessBeforeInitialization1 end-------------");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("-------------postProcessAfterInitialization1 start-------------");
System.out.println("bean: " + bean);
System.out.println("beanName: " + beanName);
System.out.println("-------------postProcessAfterInitialization1 end-------------");
return bean;
}
/**
* @return 返回值越小,执行优先级越高
*/
@Override
public int getOrder() {
return 0;
}
}
public static class MyBeanPostProcessor2 implements BeanPostProcessor, Ordered {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("-------------postProcessBeforeInitialization2 start-------------");
System.out.println("bean: " + bean);
System.out.println("beanName: " + beanName);
System.out.println("-------------postProcessBeforeInitialization2 end-------------");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("-------------postProcessAfterInitialization2 start-------------");
System.out.println("bean: " + bean);
System.out.println("beanName: " + beanName);
System.out.println("-------------postProcessAfterInitialization2 end-------------");
return bean;
}
/**
* @return 返回值越小,执行优先级越高
*/
@Override
public int getOrder() {
return 2;
}
}
}
配置文件:
<bean class="com.spring.source.MyBeanPostProcessor.MyBeanPostProcessor1" id="myBeanPostProcessor1"/>
<bean class="com.spring.source.MyBeanPostProcessor.MyBeanPostProcessor2" id="myBeanPostProcessor2"/>
<bean class="com.spring.source.BeanPostProcessorTest" id="beanPostProcessorTest" init-method="init">
<property name="string" value="str1"/>
bean>
测试:
@Test
public void beanPostProcessorTest() {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("spring-config-test.xml");
//手动注入,不会触发BeanPostProcessor回调
ac.getBeanFactory().registerSingleton("beanPostProcessorTest2", new BeanPostProcessorTest("registerSingleton"));
}
结果如下:
无参构造器调用
setter调用
-------------postProcessBeforeInitialization1 start-------------
bean: BeanPostProcessorTest{string='str1'}
beanName: beanPostProcessorTest
-------------postProcessBeforeInitialization1 end-------------
-------------postProcessBeforeInitialization2 start-------------
bean: BeanPostProcessorTest{string='str1'}
beanName: beanPostProcessorTest
-------------postProcessBeforeInitialization2 end-------------
+++++++++++++++ init-method +++++++++++++++++++
-------------postProcessAfterInitialization1 start-------------
bean: BeanPostProcessorTest{string='str1'}
beanName: beanPostProcessorTest
-------------postProcessAfterInitialization1 end-------------
-------------postProcessAfterInitialization2 start-------------
bean: BeanPostProcessorTest{string='str1'}
beanName: beanPostProcessorTest
-------------postProcessAfterInitialization2 end-------------
带参构造器调用
单纯的使用的话,还是比较简单的!
ApplicationContextAwareProcessor实现了BeanPostProcessor后置处理器接口,是Spring自带的后置处理器。用于向实现了Aware接口的子接口EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAwarebean的bean中注入相应的属性。
这里的注入就是:先判断属于某个类型,然后转换换为该类型,并调用相关方法。
/**
* Spring提供的后置处理器接口的实现
*
* 用于向实现了Aware接口的子接口EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、
* ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAwarebean的bean中注入相应的属性。
*/
class ApplicationContextAwareProcessor implements BeanPostProcessor {
private final ConfigurableApplicationContext applicationContext;
private final StringValueResolver embeddedValueResolver;
/**
* Create a new ApplicationContextAwareProcessor for the given context.
*/
public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {
this.applicationContext = applicationContext;
this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory());
}
/**
* 主要看postProcessBeforeInitialization方法
*/
@Override
@Nullable
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
/*如果bean不属于这几个接口的实例,那么返回bean,相当于什么都不做*/
if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
return bean;
}
/*否则,注入相关属性*/
AccessControlContext acc = null;
if (System.getSecurityManager() != null) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}
if (acc != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareInterfaces(bean);
return null;
}, acc);
} else {
//主要看invokeAwareInterfaces方法
invokeAwareInterfaces(bean);
}
return bean;
}
/**
* 根据属性类型,然后将之转型,并调用相关方法将属性注入进去,还是比较简单的
*
* @param bean 拦截到的bean
*/
private void invokeAwareInterfaces(Object bean) {
//属于某个类型
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);
}
}
}
beanFactory的ignoreDependencyType方法用于忽略该类型及其子类作为参数的setter自动注入设置(byName或者byType),不能忽略constructor的自动注入。相比于ignoreDependencyInterface方法,ignoreDependencyType方法范围更广。在后面的doCreateBean方法中我们就会见到这两个扩展点!
我们添加一个测试类,该类具有同名方法,但是没有实现Ignore接口:
/**
* @author lx
*/
public class IgnoreOther {
private PoJoA poJoA;
private PoJoB poJoB;
public void setPoJoA(PoJoA poJoA) {
this.poJoA = poJoA;
}
public void setPoJoB(PoJoB poJoB) {
this.poJoB = poJoB;
}
public IgnoreOther(PoJoA poJoA, PoJoB poJoB) {
this.poJoA = poJoA;
this.poJoB = poJoB;
}
public IgnoreOther() {
}
@Override
public String toString() {
return "IgnoreOther{" +
"poJoA=" + poJoA +
", poJoB=" + poJoB +
'}';
}
}
添加配置:
<bean class="com.spring.source.ingoreInterface.IgnoreOther"
id="IgnoreOtherByType" autowire="byType"/>
<bean class="com.spring.source.ingoreInterface.IgnoreOther" id="IgnoreOtherByName" autowire="byName"/>
<bean class="com.spring.source.ingoreInterface.IgnoreOther" id="IgnoreOtherByConstructor" autowire="constructor"/>
开启beanFactory.ignoreDependencyInterface(Ignore.class),测试:
IgnoreImpl{poJoA=null, poJoB=null}
IgnoreImpl{poJoA=null, poJoB=null}
IgnoreImpl{poJoA=com.spring.source.ingoreInterface.IgnoreImpl$PoJoA@25bbf683, poJoB=com.spring.source.ingoreInterface.IgnoreImpl$PoJoB@6ec8211c}
---------------
IgnoreOther{poJoA=com.spring.source.ingoreInterface.IgnoreImpl$PoJoA@25bbf683, poJoB=com.spring.source.ingoreInterface.IgnoreImpl$PoJoB@6ec8211c}
IgnoreOther{poJoA=com.spring.source.ingoreInterface.IgnoreImpl$PoJoA@25bbf683, poJoB=com.spring.source.ingoreInterface.IgnoreImpl$PoJoB@6ec8211c}
IgnoreOther{poJoA=com.spring.source.ingoreInterface.IgnoreImpl$PoJoA@25bbf683, poJoB=com.spring.source.ingoreInterface.IgnoreImpl$PoJoB@6ec8211c}
可以发现,由于IgnoreOther不属于Ignore体系,因此它的自动注入不受影响。
我们换成ignoreDependencyType方法:
/**
* beanFactory的后置处理器
*/
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
//开启这段代码时,即使设置了byName或者byType自动注入并且满足条件
//也不会调用Ignore接口及其实现类中的定义的setter方法进行自动注入
//beanFactory.ignoreDependencyInterface(Ignore.class);
//这样也行
//beanFactory.ignoreDependencyInterface(IgnoreImpl.class);
//忽略该类型及其子类作为参数的setter自动注入设置(byName或者byType),不能忽略constructor的自动注入。
beanFactory.ignoreDependencyType(IgnoreImpl.PoJoA.class);
beanFactory.ignoreDependencyType(IgnoreImpl.PoJoB.class);
}
继续测试,结果如下:
IgnoreImpl{poJoA=null, poJoB=null}
IgnoreImpl{poJoA=null, poJoB=null}
IgnoreImpl{poJoA=com.spring.source.ingoreInterface.IgnoreImpl$PoJoA@543c6f6d, poJoB=com.spring.source.ingoreInterface.IgnoreImpl$PoJoB@13eb8acf}
---------------
IgnoreOther{poJoA=null, poJoB=null}
IgnoreOther{poJoA=null, poJoB=null}
IgnoreOther{poJoA=com.spring.source.ingoreInterface.IgnoreImpl$PoJoA@543c6f6d, poJoB=com.spring.source.ingoreInterface.IgnoreImpl$PoJoB@13eb8acf}
可以发现IgnoreOther的setter自动注入也配忽略了。
beanFactory的ignoreDependencyInterface方法用于忽略该类型及其子类的相关方法的setter自动注入设置(byName或者byType),不能忽略constructor的自动注入。
测试类:
/**
* @author lx
*/
public interface Ignore {
void setPoJoA(IgnoreImpl.PoJoA poJoA);
void setPoJoB(IgnoreImpl.PoJoB poJoB);
}
//--------------------------
/**
* @author lx
*/
public class IgnoreImpl implements Ignore {
private PoJoA poJoA;
private PoJoB poJoB;
@Override
public void setPoJoA(PoJoA poJoA) {
this.poJoA = poJoA;
}
@Override
public void setPoJoB(PoJoB poJoB) {
this.poJoB = poJoB;
}
public IgnoreImpl(PoJoA poJoA, PoJoB poJoB) {
this.poJoA = poJoA;
this.poJoB = poJoB;
}
public IgnoreImpl() {
}
@Override
public String toString() {
return "IgnoreImpl{" +
"poJoA=" + poJoA +
", poJoB=" + poJoB +
'}';
}
public static class PoJoA{
}
public static class PoJoB{
}
}
自定义beanFactory的后置处理器(后面马上会讲):
/**
* 测试Ignore
*
* @author lx
*/
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
/**
* beanFactory的后置处理器
*/
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
//开启这段代码时,即使设置了byName或者byType自动注入并且满足条件
//也不会调用Ignore接口及其实现类中的定义的setter方法进行自动注入
beanFactory.ignoreDependencyInterface(Ignore.class);
//这样也行
//beanFactory.ignoreDependencyInterface(IgnoreImpl.class);
}
}
配置文件:
<bean class="com.spring.source.ingoreInterface.MyBeanFactoryPostProcessor" id="beanFactoryPostProcessor"/>
<bean class="com.spring.source.ingoreInterface.IgnoreImpl.PoJoA" id="poJoA"/>
<bean class="com.spring.source.ingoreInterface.IgnoreImpl.PoJoB" id="poJoB"/>
<bean class="com.spring.source.ingoreInterface.IgnoreImpl" id="ignoreByType" autowire="byType"/>
<bean class="com.spring.source.ingoreInterface.IgnoreImpl" id="ignoreByName" autowire="byName"/>
<bean class="com.spring.source.ingoreInterface.IgnoreImpl" id="ignoreByConstructor" autowire="constructor"/>
测试:
@Test
public void ignoreDependencyInterface() {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("spring-config-test.xml");
System.out.println(ac.getBean("ignoreByName"));
System.out.println(ac.getBean("ignoreByType"));
System.out.println(ac.getBean("ignoreByConstructor"));
}
结果如下:
IgnoreImpl{poJoA=null, poJoB=null}
IgnoreImpl{poJoA=null, poJoB=null}
IgnoreImpl{poJoA=com.spring.source.ingoreInterface.IgnoreImpl$PoJoA@4e718207, poJoB=com.spring.source.ingoreInterface.IgnoreImpl$PoJoB@1d371b2d}
当注释掉ignoreDependencyInterface代码时,结果如下:
IgnoreImpl{poJoA=com.spring.source.ingoreInterface.IgnoreImpl$PoJoA@1990a65e, poJoB=com.spring.source.ingoreInterface.IgnoreImpl$PoJoB@64485a47}
IgnoreImpl{poJoA=com.spring.source.ingoreInterface.IgnoreImpl$PoJoA@1990a65e, poJoB=com.spring.source.ingoreInterface.IgnoreImpl$PoJoB@64485a47}
IgnoreImpl{poJoA=com.spring.source.ingoreInterface.IgnoreImpl$PoJoA@1990a65e, poJoB=com.spring.source.ingoreInterface.IgnoreImpl$PoJoB@64485a47}
当使用byType自动注入或者使用@Autowired注解自动注入时,如果同一个类型的bean在Spring中存在多个,由于Spring可能不知道使用那一个bean实例,因此可能会抛出异常。
beanFactory的registerResolvableDependency方法的主要作用就是在容器启动阶段指定某个类型及其某个实现,如果运行时外部要注入该类型的对象,并且无法找到最合适的依赖,则会注入我们指定的对象实例,指定的类型和对应的实例将被缓存在resolvableDependencies缓存中!
在后面的doCreateBean方法中我们会再次见到这个扩展点,到时后我们会讲解具体的匹配规则!
在prepareBeanFactory中我们知道可以Spring预定义的注册了一批自动注入的对象直,包括BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext这几个类型。首先我们来测试预定义的自动注入实例:
public class AutoRegister {
private BeanFactory beanFactory;
private ResourceLoader resourceLoader;
private ApplicationEventPublisher applicationEventPublisher;
private ApplicationContext applicationContext;
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;
}
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
@Override
public String toString() {
return "AutoRegister{" +
"beanFactory=" + beanFactory +
", resourceLoader=" + resourceLoader +
", applicationEventPublisher=" + applicationEventPublisher +
", applicationContext=" + applicationContext +
'}';
}
}
配置,注意自动注入类型需要选择byType:
<bean class="com.spring.source.registerResolvable.AutoRegister" id="autoRegister" autowire="byType"/>
测试:
@Test
public void registerResolvable() {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("spring-config-test.xml");
System.out.println(ac.getBean("autoRegister"));
}
结果如下,成功的注入了值,虽然我们并没有将这几个对象实例亲自交给IoC容器,但还是从容器中成功获取到了对象,这实际上就是Spring在这一步帮我们做的。
AutoRegister{beanFactory=org.springframework.beans.factory.support.DefaultListableBeanFactory@55d56113: defining beans [autoRegister,myRDBeanFactoryPostProcessor,rdImplA,rdImplB,rd]; root of factory hierarchy,
resourceLoader=org.springframework.context.support.ClassPathXmlApplicationContext@2a098129, started on Sun Sep 27 14:40:34 CST 2020,
applicationEventPublisher=org.springframework.context.support.ClassPathXmlApplicationContext@2a098129, started on Sun Sep 27 14:40:34 CST 2020,
applicationContext=org.springframework.context.support.ClassPathXmlApplicationContext@2a098129, started on Sun Sep 27 14:40:34 CST 2020}
想要自定义自动注入实例,很简单,同样只需要实现BeanFactoryPostProcessor接口重写postProcessBeanFactory方法就行了。
测试类:
public interface ResolvableDependency {}
//------------------
public class RDImpl {
/**
* 尝试自动注入该属性
*/
private ResolvableDependency resolvableDependency;
public void setResolvableDependency(ResolvableDependency resolvableDependency) {
this.resolvableDependency = resolvableDependency;
}
@Override
public String toString() {
return "RDImpl{" +
"resolvableDependency=" + resolvableDependency +
'}';
}
public static class RDImplA implements ResolvableDependency {}
public static class RDImplB implements ResolvableDependency {}
}
自定义beanFactory后置处理器:
/**
* 测试ResolvableDependency
*
* @author lx
*/
public class MyRDBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
/**
* beanFactory的后置处理器
*/
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
RDImpl.RDImplA rdImplA= new RDImpl.RDImplA();
System.out.println(rdImplA);
beanFactory.registerResolvableDependency(ResolvableDependency.class,rdImplA);
}
}
配置文件:
<bean class="com.spring.source.registerResolvable.MyRDBeanFactoryPostProcessor" id="myRDBeanFactoryPostProcessor"/>
<bean class="com.spring.source.registerResolvable.RDImpl.RDImplA" id="rdImplA"/>
<bean class="com.spring.source.registerResolvable.RDImpl.RDImplB" id="rdImplB"/>
<bean class="com.spring.source.registerResolvable.RDImpl" id="rd" autowire="byType"/>
测试:
@Test
public void myRegisterResolvable() {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("spring-config-test.xml");
System.out.println(ac.getBean("rd"));
System.out.println(ac.getBean("rdImplA"));
System.out.println(ac.getBean("rdImplB"));
}
结果如下,成功的自动注入,并且注入的是我们指定的对象:
com.spring.source.registerResolvable.RDImpl$RDImplA@4f063c0a
RDImpl{resolvableDependency=com.spring.source.registerResolvable.RDImpl$RDImplA@4f063c0a}
com.spring.source.registerResolvable.RDImpl$RDImplA@1d371b2d
com.spring.source.registerResolvable.RDImpl$RDImplB@543c6f6d
如果去掉registerResolvableDependency的代码,那么就是熟悉的异常了,因为有两个同类型的依赖并且无法选择最合适的一个:
expected single matching bean but found 2: rdImplA,rdImplB
当然,这个扩展点现在很少被使用,因为有其他很多方法能够指定使用某个实例,比如primary属性、autowire-candidate属性或者其他注解,比如@Qualifier!
在prepareBeanFactory方法中,会手动注册三个单例bean的实例:environment、systemProperties、systemEnvironment,主要是将它们的实例注册到DefaultSingletonBeanRegistry注册表的缓存中,而这个注册表专门用于管理单例bean实例的缓存。
我们自己也能调用这个方法注册单例bean,手动注册的单例bean不受其他回调方法的影响。
/**
* DefaultListableBeanFactory的方法
*
* 手动注册bean及其实例
*
* @param beanName beanName
* @param singletonObject 单例的bean实例
*/
@Override
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
//调用父类的方法DefaultSingletonBeanRegistry注册到父类的相应的bean实例缓存中
super.registerSingleton(beanName, singletonObject);
//更新DefaultListableBeanFactory工厂内部的手动注册的单例bean的名字缓存manualSingletonNames
//如果不包含给定beanName,那么添加beanName
updateManualSingletonNames(set -> set.add(beanName), set -> !this.beanDefinitionMap.containsKey(beanName));
//删除有关按类型映射的任何缓存,即清空allBeanNamesByType和singletonBeanNamesByType属性集合
clearByTypeCache();
}
//-------父类DefaultSingletonBeanRegistry的一些属性------
/**
* bean name 到 bean instance 的单例bean的缓存map(单例bean)
*/
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/**
* bean name 到 ObjectFactory 的单例bean的缓存map(单例工厂)
*/
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
/**
* bean name 到 bean instance 的早期单例bean的缓存map(早期单例bean)
* 用于解决循环依赖
*/
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
/**
* 已注册的单例实例按注册顺序设置的beanName。
*/
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
/**
* 父类DefaultSingletonBeanRegistry的方法
*
* @param beanName beanName
* @param singletonObject 单例的bean实例
*/
@Override
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
//非空断言,不符合就抛出异常
Assert.notNull(beanName, "Bean name must not be null");
Assert.notNull(singletonObject, "Singleton object must not be null");
//加锁
synchronized (this.singletonObjects) {
//从缓存中获取尝试获取该名字单例bean实例
Object oldObject = this.singletonObjects.get(beanName);
//如果不为null,说明重复注册,抛出异常
if (oldObject != null) {
throw new IllegalStateException("Could not register object [" + singletonObject +
"] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
}
//注册
addSingleton(beanName, singletonObject);
}
}
/**
* 父类DefaultSingletonBeanRegistry的方法
*
* 将给定的单例对象添加到此工厂的单例缓存中。
*
* @param beanName beanName
* @param singletonObject 单例对象
*/
protected void addSingleton(String beanName, Object singletonObject) {
//加锁
synchronized (this.singletonObjects) {
//注册到singletonObjects缓存
this.singletonObjects.put(beanName, singletonObject);
//上面的缓存中注册了,那么其他单例缓存中就不应该出现
//singletonFactories和earlySingletonObjects移除
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
//注册到beanName缓存
this.registeredSingletons.add(beanName);
}
}
prepareBeanFactory方法是对BeanFactory的一些默认配置,prepareBeanFactory方法执行完毕之后,此时所有 bean 定义都已被加载,但尚未实例化任何 bean。
此时将继续执行postProcessBeanFactory方法。postProcessBeanFactory方法默认是一个空的实现,这是留给BeanFactory的自定义子类实现的方法,用于对于BeanFactory做出自定义的修改,比如前面将的注册一些BeanPostProcessors、忽略setter自动注入扩展点、指定自动注入实例等等功能。
后面我们会讲到BeanFactoryPostProcessor扩展接口,它具有同样的功能,并且更加灵活,因此这里的这个扩展点很少被使用的(因为这需要自定义容器的子类)。
/**
* AbstractApplicationContext的方法
*
* 在应用程序上下文的标准初始化后用于修改其内部的 beanFactory。
* 所有 bean 定义都将已加载,但尚未实例化任何 bean。这允许在某些应用程序上下文实现中注册特殊的 BeanPost 处理器等。
*
* @param beanFactory 当前应用程序上下文使用的 bean 工厂
*/
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
//空实现
}
如果子类容器要定义自己的BeanFactory逻辑,那么重写该方法就行了:
/**
* @author lx
*/
public class MyPostProcessClassPathXmlApplicationContext extends ClassPathXmlApplicationContext {
public MyPostProcessClassPathXmlApplicationContext(String... s) {
super(s);
}
/**
* 重写该方法就行了
*
* @param beanFactory postProcess
*/
@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
super.postProcessBeanFactory(beanFactory);
//---------自己的逻辑------------
}
}
BeanFactoryPostProcessor同样作为Spring对外提供的最重要的扩展点之一。它的postProcessBeanFactory回调方法用于在应用程序上下文的标准初始化后修改其内部 bean 工厂。此时所有 bean 定义都将已加载,但尚未实例化任何 bean。也就是说,这允许我们重写beandefinition或添加beandefinition,修改beanFactory中的beandefinition的任何可以修改的地方。
而前面学习的BeanPostProcessor扩展接口则用于管理已经被实例化之后的bean实例。因此,BeanFactoryPostProcessor的回调比BeanPostProcessor要早。它属于一个比较早期的扩展点。
@FunctionalInterface
public interface BeanFactoryPostProcessor {
/**
* 在应用程序上下文的标准初始化后修改其内部 bean 工厂。所有 bean 定义都将已加载,但尚未实例化任何 bean。
* 这允许重写或添加属性,修改 bean 定义任何可以修改的地方。
*
* @param beanFactory 应用程序上下文容器使用的bean工厂
*/
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor,同时具有自己的新方法。BeanDefinitionRegistryPostProcessor的回调比BeanFactoryPostProcessor还要早。
它的postProcessBeanDefinitionRegistry回调方法用于在应用程序上下文的标准初始化后修改其内部 bean 定义注册表。此时所有常规 bean 定义都将已加载,但尚未实例化任何 bean。也就是说,这允许我们在下一个BeanFactoryPostProcessor后处理阶段开始之前添加更多的 bean 定义。
BeanDefinitionRegistryPostProcessor后处理器用于我们自定义的添加更多的beandefinition。它非常的有用,比如dubbo自己的service扫描,就是用了一个ServiceAnnotationBeanPostProcessor后处理器,将指定路径下具有Dubbo的@service注解的类添加到bean定义中,又比如mybatis的basePackage扫描,就是使用MapperScannerConfigurer后处理器,将指定目录下的mapper接口添加到bean定义中。
最著名的ConfigurationClassPostProcessor后处理器也是该类型的实现,它的postProcessBeanDefinitionRegistry用于解析配置类以及各种配置注解@Configuration 、@Component、@ComponentScan、@Import、@ImportResource……,@Bean注解也是在这里解析的,解析的bean定义会被注册到注册表中!
public interface BeanDefinitionRegistryPostProcessor extends
BeanFactoryPostProcessor {
/**
* 在应用程序上下文的标准初始化后修改其内部 bean 定义注册表。所有常规 bean 定义都将已加载,但尚未实例化任何 bean。
* 这允许在下一个后处理阶段开始之前添加更多的 bean 定义。
*
* @param registry 应用程序上下文容器使用的 bean 定义注册表
* @throws org.springframework.beans.BeansException in case of errors
*/
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}
invokeBeanFactoryPostProcessors方法就是用于实例化并调用所有注册的BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor,如果给出显式顺序,则遵守显式顺序。内部的postProcessBeanDefinitionRegistry方法和postProcessBeanFactory方法必须在普通单例bean实例化之前调用。
由于此时bean还没有开始实例化,因此在扩展的BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor中不应该调用实例bean的相关方法或者那些会触发bean实例化的方法。
invokeBeanFactoryPostProcessors方法的内部实际上主要调用代理类PostProcessorRegistrationDelegate的静态方法invokeBeanFactoryPostProcessors,传入beanFactory 以及 上下文容器中的beanFactoryPostProcessors集合来完成回调BeanFactory后处理器的功能的。
/**
* AbstractApplicationContext的方法
*
* 实例化并调用所有注册的BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor
* 具有先后顺序,如果给出显式顺序,则遵守显式顺序。
*/
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
/*
* 调用代理类PostProcessorRegistrationDelegate的静态方法invokeBeanFactoryPostProcessors
* 传入beanFactory 以及 上下文容器中的beanFactoryPostProcessors集合
*/
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// 检测LoadTimeWeaver,并为织入做准备
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
beanFactoryPostProcessors是一个集合,当我们自己调用上下文容器的addBeanFactoryPostProcessor方法手动注册beanFactoryPostProcessor时,添加的beanFactoryPostProcessor就被放入该集合中。我们也可以通过bean定义的方法注册BeanFactoryPostProcessor。这是两个不同的数据来源!
在后续回调方法被调用的时候,beanFactoryPostProcessors集合中的beanFactoryPostProcessor的相关方法将会被最先回调。
/**
* AbstractApplicationContext的beanFactoryPostProcessors集合
*
* 当调用上下文容器的addBeanFactoryPostProcessor方法手动注册beanFactoryPostProcessor时
* 添加的BeanFactoryPostProcessor就放入该集合中
*/
private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors = new ArrayList<>();
/**
1. AbstractApplicationContext的方法
2.
3. 从上下文容器中返回beanFactoryPostProcessors。
*/
public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
return this.beanFactoryPostProcessors;
}
通常情况下,beanFactoryPostProcessors是一个空集合,那么这个addBeanFactoryPostProcessor方法我们自己如何调用呢?
基于非web和web容器都有自己的调用方式,Spring Boot也有自己的调用方式。这里我们就讲非web容器的调用方式。
在最开始我们讲过一个扩展方法initPropertySources,在那个方法中就可以调用addBeanFactoryPostProcessor方法添加我们自定义的beanFactoryPostProcessor到beanFactoryPostProcessors集合中,而在上面的prepareBeanFactory扩展方法中也能调用addBeanFactoryPostProcessor方法。不过通常我们自定义的beanFactoryPostProcessor也是通过bean定义的方式加载的。
BeanFactoryPostProcessor有两个总的来源,一个是通过普通bean定义的方式注册到beanFactory的缓存中,在回调时会将它们筛选出来并且进行初始化;另一个就是通过调用上下文容器的addBeanFactoryPostProcessor方法手动注册的beanFactoryPostProcessor实例,它们被放入AbstractApplicationContext的beanFactoryPostProcessors集合中。
invokeBeanFactoryPostProcessors方法对于上面两个来源的beanFactoryPostProcessor的回调是有先后顺序的,回调顺序如下:
流程图如下:
源码解析如下,代码比较多,一定要分块解析。关于排序的规则,在sortPostProcessors源码解析部分。
/**
* PostProcessorRegistrationDelegate的方法
*
* 实例化并调用所有注册的BeanFactoryPostProcessor(包括BeanDefinitionRegistryPostProcessor),如果给出显式顺序,则遵守显式顺序。
*
* @param beanFactory bean工厂,BeanFactoryPostProcessor的来源之一,通过bean定义
* @param beanFactoryPostProcessors 上下文容器中的beanFactoryPostProcessors集合,BeanFactoryPostProcessor的来源之二,通过手动注册
*/
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
//要执行回调方法和已执行回调方法的beanName集合,用于防止重复回调
Set<String> processedBeans = new HashSet<>();
/*beanFactory是否属于BeanDefinitionRegistry,一般都是,所有都会走这一个逻辑*/
if (beanFactory instanceof BeanDefinitionRegistry) {
//beanFactory强转为BeanDefinitionRegistry类型
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
//这个集合保存BeanFactoryPostProcessor类型的后置处理器实例(用于最后执行postProcessBeanFactory回调方法)
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
//这个集合保存BeanDefinitionRegistryPostProcessor类型的后置处理器实例(用于最后执行postProcessBeanFactory回调方法)
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
/*
* 1 首先遍历、处理beanFactoryPostProcessors集合
* 对于BeanDefinitionRegistryPostProcessor类型的对象回调postProcessBeanDefinitionRegistry方法
* 并加入registryProcessors集合中,非这个类型的BeanFactoryPostProcessor加入regularPostProcessors集合中
*/
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
/*1.1 如果属于BeanDefinitionRegistryPostProcessor类型*/
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
//postProcessor强转为BeanDefinitionRegistryPostProcessor类型
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
/*1.1.1 按照遍历顺序,回调postProcessBeanDefinitionRegistry方法*/
registryProcessor.postProcessBeanDefinitionRegistry(registry);
//1.1.2 加入到registryProcessors集合中(用于最后执行postProcessBeanFactory回调方法)
registryProcessors.add(registryProcessor);
}
/*1.2 如果不属于BeanDefinitionRegistryPostProcessor类型*/
else {
//1.2.1 加入到regularPostProcessors集合中
regularPostProcessors.add(postProcessor);
}
}
//这个集合临时保存当前准备创建并执行回调的BeanDefinitionRegistryPostProcessor类型的后置处理器实例,毁掉完毕即清理
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
/*
* 2 对于beanFactory中,所有实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor类型的bean定义进行实例化
* 随后对这一批BeanDefinitionRegistryPostProcessor实例进行排序,最后按照排序顺序从前向后回调postProcessBeanDefinitionRegistry方法
*/
// 从beanFactory中获取所有BeanDefinitionRegistryPostProcessor类型的bean定义的名称数组
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
//遍历beanFactory中的BeanDefinitionRegistryPostProcessor类型的bean定义的名称数组
for (String ppName : postProcessorNames) {
//如果该名称的bean定义还实现了PriorityOrdered接口
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//当前beanName的BeanDefinitionRegistryPostProcessor实例加入到currentRegistryProcessors集合
//这个getBean方法实际上已经将bean实例创建出来了
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//加入到processedBeans集合
processedBeans.add(ppName);
}
}
//到这一步currentRegistryProcessors集合的元素都是实现了PriorityOrdered接口的类型实例
//这里对currentRegistryProcessors集合的元素根据Ordered顺序进行排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
//currentRegistryProcessors整体加入到registryProcessors集合中(用于最后执行postProcessBeanFactory回调方法)
registryProcessors.addAll(currentRegistryProcessors);
//对于currentRegistryProcessors集合中的已排序的BeanDefinitionRegistryPostProcessor按照顺序从前向后回调postProcessBeanDefinitionRegistry方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//回调完毕之后清空currentRegistryProcessors集合
currentRegistryProcessors.clear();
/*
* 3 对于beanFactory中,所有实现了Ordered接口的BeanDefinitionRegistryPostProcessor类型的bean定义进行实例化(排除上一步调用过的处理器)
* 随后对这一批BeanDefinitionRegistryPostProcessor实例进行排序,最后按照排序顺序从前向后回调postProcessBeanDefinitionRegistry方法
*/
//重新从beanFactory中获取所有BeanDefinitionRegistryPostProcessor类型的bean定义的名称数组
//因为此时可能有新增的BeanDefinitionRegistryPostProcessor定义,比如在上面执行的回调方法中又新增了BeanDefinitionRegistryPostProcessor定义
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
//遍历beanFactory中的BeanDefinitionRegistryPostProcessor类型的bean定义的名称数组
for (String ppName : postProcessorNames) {
//如果processedBeans集合不包含该名称(防止重复回调),并且该名称的bean定义还实现了PriorityOrdered接口
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
//当前beanName的BeanDefinitionRegistryPostProcessor实例加入到currentRegistryProcessors集合
//这个getBean方法实际上已经将bean实例创建出来了
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//加入到processedBeans集合
processedBeans.add(ppName);
}
}
//到这一步currentRegistryProcessors集合的元素都是实现了Ordered接口的类型实例
//这里对currentRegistryProcessors集合的元素根据Ordered顺序进行排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
//currentRegistryProcessors整体加入到registryProcessors集合中(用于最后执行postProcessBeanFactory回调方法)
registryProcessors.addAll(currentRegistryProcessors);
//对于currentRegistryProcessors集合中的已排序的BeanDefinitionRegistryPostProcessor按照顺序从前向后回调postProcessBeanDefinitionRegistry方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//回调完毕之后清空currentRegistryProcessors集合
currentRegistryProcessors.clear();
/*
* 4 对于beanFactory中,所有剩余的普通的BeanDefinitionRegistryPostProcessor类型的bean定义进行实例化
* 随后对这一批BeanDefinitionRegistryPostProcessor实例进行排序,最后按照排序顺序从前向后回调postProcessBeanDefinitionRegistry方法
*
* 这一步将会一直循环重试,直到bean定义中不再出现新的BeanDefinitionRegistryPostProcessors,
* 因为在上面执行的postProcessBeanDefinitionRegistry回调方法中可能又新增了BeanDefinitionRegistryPostProcessor类型的bean定义
*/
//重试标志
boolean reiterate = true;
while (reiterate) {
//重试标志改为false
reiterate = false;
//重新从beanFactory中获取所有BeanDefinitionRegistryPostProcessor类型的bean定义的名称数组
//因为此时可能有新增的BeanDefinitionRegistryPostProcessor定义,比如在上面执行的回调方法中又新增了BeanDefinitionRegistryPostProcessor定义
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
//遍历beanFactory中的BeanDefinitionRegistryPostProcessor类型的bean定义的名称数组
for (String ppName : postProcessorNames) {
//如果processedBeans集合不包含该名称(防止重复回调)
if (!processedBeans.contains(ppName)) {
//当前beanName的BeanDefinitionRegistryPostProcessor实例加入到currentRegistryProcessors集合
//这个getBean方法实际上已经将bean实例创建出来了
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//加入到processedBeans集合
processedBeans.add(ppName);
//重试标志改为true,这表示将会重试
//因为上面的有新加入的BeanDefinitionRegistryPostProcessor定义,而调用它们的回调方法时,可能在回调方法中又新增了BeanDefinitionRegistryPostProcessor定义
//因此,只要如果processedBeans集合不包含某些beanName,那么就会进入下一次回调
reiterate = true;
}
}
//到这一步currentRegistryProcessors集合的元素都是剩下的实例,它们即没有实现Ordered接口也没有实现PriorityOrdered接口
//或者是在回调方法中新增的BeanDefinitionRegistryPostProcessor定义(它们有可能实现Ordered接口或者PriorityOrdered接口),因此还是需要排序
//这里对currentRegistryProcessors集合的元素根据Ordered顺序进行排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
//currentRegistryProcessors整体加入到registryProcessors集合中(用于最后执行postProcessBeanFactory回调方法)
registryProcessors.addAll(currentRegistryProcessors);
//对于currentRegistryProcessors集合中的已排序的BeanDefinitionRegistryPostProcessor按照顺序从前向后回调postProcessBeanDefinitionRegistry方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//回调完毕之后清空currentRegistryProcessors集合
currentRegistryProcessors.clear();
}
//到这一步,出了循环,所有的BeanDefinitionRegistryPostProcessor类型的bean定义已被实例化完毕
//并且它们的postProcessBeanDefinitionRegistry方法已完成回调
/*
* 此时registryProcessors集合中包含beanFactoryPostProcessors和beanFactory中的全部BeanDefinitionRegistryPostProcessor
* 此时regularPostProcessors集合中包含beanFactoryPostProcessors中的全部BeanFactoryPostProcessor
*
* 5 最后,对于registryProcessors中的全部BeanDefinitionRegistryPostProcessor从前向后回调postProcessBeanFactory方法
* 对于regularPostProcessors中的全部BeanFactoryPostProcessor从前向后回调postProcessBeanFactory方法
*/
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
/*否则,直接对于beanFactoryPostProcessors集合中的全部实例从前向后回调postProcessBeanFactory方法*/
else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
/*
* 到这一步,beanFactoryPostProcessors和beanFactory中的全部BeanDefinitionRegistryPostProcessor已完成postProcessBeanDefinitionRegistry方法和postProcessBeanFactory方法的回调
* 到这一步,beanFactoryPostProcessors中的全部BeanFactoryPostProcessor已完成postProcessBeanFactory方法的回调
*
* 到这一步,还剩下beanFactory中的全部BeanFactoryPostProcessor还没有完成postProcessBeanFactory方法的回调,下面的代码就是完成这个工作
*/
// 从beanFactory中获取所有BeanFactoryPostProcessor类型的bean定义的名称数组
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
//这个集合保存实现了PriorityOrdered接口的BeanFactoryPostProcessor实例
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
//这个集合保存实现了Ordered接口的BeanFactoryPostProcessor的beanName
List<String> orderedPostProcessorNames = new ArrayList<>();
//这个集合保存普通的BeanFactoryPostProcessor的beanName
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
//遍历postProcessorNames数组,填充数据
for (String ppName : postProcessorNames) {
/*如果processedBeans集合包含该名称*/
if (processedBeans.contains(ppName)) {
//什么都不做,防止重复回调
// skip - already processed in first phase above
}
/*否则,如果该名称的bean定义还实现了PriorityOrdered接口*/
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//当前beanName的BeanFactoryPostProcessor实例加入到priorityOrderedPostProcessors集合
//这个getBean方法实际上已经将bean实例创建出来了
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
/*否则,如果该名称的bean定义还实现了Ordered接口*/
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
//当前beanName加入到orderedPostProcessorNames集合
orderedPostProcessorNames.add(ppName);
}
/*否则,当前beanName加入到nonOrderedPostProcessorNames集合*/
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
/*
* 6 对于beanFactory中,所有实现了PriorityOrdered接口的BeanFactoryPostProcessor实例进行排序
* 随后按照排序顺序从前向后回调postProcessBeanFactory方法
*/
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
//这里对priorityOrderedPostProcessors集合的元素根据Ordered顺序进行排序
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
//对于priorityOrderedPostProcessors集合中的已排序的BeanFactoryPostProcessor按照顺序从前向后回调postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
/*
* 7 对于beanFactory中,所有实现了Ordered接口的BeanFactoryPostProcessor的bean定义进行实例化并且进行排序
* 随后按照排序顺序从前向后回调postProcessBeanFactory方法
*/
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
//这个集合保存实现了Ordered接口的BeanFactoryPostProcessor实例
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
//遍历orderedPostProcessorNames数组,填充数据
for (String postProcessorName : orderedPostProcessorNames) {
//当前beanName的BeanFactoryPostProcessor实例加入到priorityOrderedPostProcessors集合
//这个getBean方法实际上已经将bean实例创建出来了
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
//这里对orderedPostProcessors集合的元素根据Ordered顺序进行排序
sortPostProcessors(orderedPostProcessors, beanFactory);
//对于orderedPostProcessors集合中的已排序的BeanFactoryPostProcessor按照顺序从前向后回调postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
/*
* 8 最后,对于beanFactory中,普通的BeanFactoryPostProcessor的bean定义进行实例化
* 不需要进行排序了,因为没有实现Ordered接口和PriorityOrdered接口,随后按照遍历顺序从前向后回调postProcessBeanFactory方法
*/
// Finally, invoke all other BeanFactoryPostProcessors.
//这个集合保存普通的BeanFactoryPostProcessor实例
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
//遍历nonOrderedPostProcessorNames数组,填充数据
for (String postProcessorName : nonOrderedPostProcessorNames) {
//当前beanName的BeanFactoryPostProcessor实例加入到nonOrderedPostProcessors集合
//这个getBean方法实际上已经将bean实例创建出来了
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
//对于nonOrderedPostProcessors集合中的BeanFactoryPostProcessor按照顺序从前向后回调postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
/*
* 9 清除元数据缓存(mergedBeanDefinitions、allBeanNamesByType、singletonBeanNamesByType),
* 因为后处理器可能修改了原始元数据,例如, 替换值中的占位符...
*/
beanFactory.clearMetadataCache();
}
/**
* 调用给定的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry回调方法
*/
private static void invokeBeanDefinitionRegistryPostProcessors(
Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
//循环调用postProcessBeanDefinitionRegistry方法
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
}
/**
* 调用给定的BeanFactoryPostProcessor的postProcessBeanFactory回调方法
*/
private static void invokeBeanFactoryPostProcessors(
Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
//循环调用postProcessBeanFactory方法
for (BeanFactoryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanFactory(beanFactory);
}
}
sortPostProcessors方法用于对后处理器进行排序。默认比较器为OrderComparator,但是如果开启了注解支持,那么默认设置为AnnotationAwareOrderComparator,前一篇文章的registerAnnotationConfigProcessors方法部分讲过了。AnnotationAwareOrderComparator比较器可以支持PriorityOrdered接口、Ordered接口、@Ordered注解、@Priority注解的排序,比较优先级为PriorityOrdered>Ordered>@Ordered>@Priority,这里学习的OrderComparator 比较器只支持PriorityOrdered、Ordered接口的排序,比较优先级为PriorityOrdered>Ordered。如果最终没找到设置的排序值,那么返回Integer.MAX_VALUE,即最低优先级。
/**
1. PostProcessorRegistrationDelegate的方法
2.
3. 对后处理器集合进行排序方法
4. 5. @param postProcessors 需要排序的后处理器集合
6. @param beanFactory bean工厂
*/
private static void sortPostProcessors(List<?> postProcessors, ConfigurableListableBeanFactory beanFactory) {
// Nothing to sort?
if (postProcessors.size() <= 1) {
return;
}
Comparator<Object> comparatorToUse = null;
//如果beanFactory属于DefaultListableBeanFactory
if (beanFactory instanceof DefaultListableBeanFactory) {
//那么首先获取设置的比较器,默认为null
//如果开启了注解支持那么默认设置为AnnotationAwareOrderComparator,前面的registerAnnotationConfigProcessors部分讲过了
//AnnotationAwareOrderComparator具有支持@Order注解和@Priority注解的排序设置的功能
comparatorToUse = ((DefaultListableBeanFactory) beanFactory).getDependencyComparator();
}
//如果设置的比较器为null
if (comparatorToUse == null) {
//那么默认使用OrderComparator比较器
comparatorToUse = OrderComparator.INSTANCE;
}
//该集合使用比较器排序
postProcessors.sort(comparatorToUse);
}
Ordered接口和PriorityOrdered接口都是用来指定元素的顺序的接口,PriorityOrdered接口继承了Order接口。
比如现在讲的BeanFactory后处理器,如果我们想要指定某些后处理器的回调方法执行的先后顺序,那么就可以让它们实现Ordered或者PriorityOrdered接口,并通过getOrder方法返回Order顺序值。除此之外,很多地方都可以进行排序,比如AOP中指定切面中通知的回调顺序,比如注入某个类型全部实例是指定集合元素的顺序,比如Bean后处理器的回调顺序。当然我们也可以直接使用@Order注解。
在Spring中,某种一类型的多个回调对象是存放在一个集合中的,在进行回调时,会按照集合顺序从前向后依次回调。在排序时,就是通过OrderComparator比较器来对集合元素进行排序的,因此我们只有知道具体的排序规则,才能实现我们想要的结果。
OrderComparator比较器实现了Comparator接口,比较排序规则为:
/**
* OrderComparator比较器类,实现了Comparator接口
*
* 用于对集合元素进行排序,PriorityOrdered接口继承了Ordered接口
*
* 1 如果比较的二者中有一个实现了PriorityOrdered接口,那么实现了PriorityOrdered接口的对象排序在前
* 2 如果比较的二者中都实现或者都没有实现PriorityOrdered接口,那么继续比较:
* 3 分别获取两个对象的order顺序值。如果实现了Order接口,那么使用该对象的getOrder方法的返回值
* 否则order值使用Ordered.LOWEST_PRECEDENCE,即Integer.MAX_VALUE
* 4 order值越小的对象,则排序越前;相同的order值的两个对象,排序顺序是不能保证的
*/
public class OrderComparator implements Comparator<Object> {
/**
* 默认的共享的比较器实例
* 单例模式
*/
public static final OrderComparator INSTANCE = new OrderComparator();
/**
* 比较的方法,从小到大的排序
*
* @return 0 等于 负整数 小于 正整数 大于
*/
@Override
public int compare(@Nullable Object o1, @Nullable Object o2) {
//sourceProvider参数为null
return doCompare(o1, o2, null);
}
/**
* 进行比较的方法
*/
private int doCompare(@Nullable Object o1, @Nullable Object o2, @Nullable OrderSourceProvider sourceProvider) {
//o1是否属于PriorityOrdered接口的实现
boolean p1 = (o1 instanceof PriorityOrdered);
//o2是否属于PriorityOrdered接口的实现
boolean p2 = (o2 instanceof PriorityOrdered);
/*如果o1是PriorityOrdered接口的实现,并且o2不是PriorityOrdered接口的实现*/
if (p1 && !p2) {
//那么返回-1,即o1在前o2在后
return -1;
}
/*如果o2是PriorityOrdered接口的实现,并且o1不是PriorityOrdered接口的实现*/
else if (p2 && !p1) {
//那么返回1,即o1在后o2在前
return 1;
}
//到这里还没有返回,可能是两者都属于或者都不属于PriorityOrdered接口的实现,那么需要进一步比较
//获取o1的order顺序值,如果o1没有实现Ordered接口,那么返回Ordered.LOWEST_PRECEDENCE,即Integer.MAX_VALUE
int i1 = getOrder(o1, sourceProvider);
//获取o2的order顺序值,如果o2没有实现Ordered接口,那么返回Ordered.LOWEST_PRECEDENCE,即Integer.MAX_VALUE
int i2 = getOrder(o2, sourceProvider);
//返回二者的order顺序值的比较结果,order顺序值越小,那么在集合中的排序靠前
return Integer.compare(i1, i2);
}
/**
* 确定给定对象的order顺序值。
* 使用getOrder方法的返回值进行比较
*
* @param obj 要检查的对象
* @return 对象的order值,如果对象没有实现Ordered接口,那么返回Ordered.LOWEST_PRECEDENCE
*/
private int getOrder(@Nullable Object obj, @Nullable OrderSourceProvider sourceProvider) {
Integer order = null;
//sourceProvider为null,不会进入if语句
if (obj != null && sourceProvider != null) {
Object orderSource = sourceProvider.getOrderSource(obj);
if (orderSource != null) {
if (orderSource.getClass().isArray()) {
Object[] sources = ObjectUtils.toObjectArray(orderSource);
for (Object source : sources) {
order = findOrder(source);
if (order != null) {
break;
}
}
} else {
order = findOrder(orderSource);
}
}
}
//直接到这一步
return (order != null ? order : getOrder(obj));
}
/**
* 确定给定对象的order顺序值。
*
* @param obj 要检查的对象
* @return 对象的order顺序值,如果对象没有实现Ordered接口,那么返回Ordered.LOWEST_PRECEDENCE
*/
protected int getOrder(@Nullable Object obj) {
//如果对象不为null
if (obj != null) {
//调用findOrder方法获取order顺序值
Integer order = findOrder(obj);
//如果结果不为null,那么返回获取到的结果
if (order != null) {
return order;
}
}
//如果obj对象为null或者获取的order值为null
//那么直接返回Ordered.LOWEST_PRECEDENCE,即Integer.MAX_VALUE
return Ordered.LOWEST_PRECEDENCE;
}
/**
* 查找给定对象指示的order顺序值。
*
* 如果对象的类没有实现Ordered接口,那么返回null,否则返回getOrder方法的返回值
*
* @param obj the 要检查的对象
* @return 对象的order顺序值,如果对象的类没有实现Ordered接口,那么返回null
*/
@Nullable
protected Integer findOrder(Object obj) {
//如果对象的类没有实现Ordered接口,那么返回null,否则返回getOrder方法的返回值
return (obj instanceof Ordered ? ((Ordered) obj).getOrder() : null);
}
}
OrderComparator实际上还有一个子类AnnotationAwareOrderComparator,当我们配置了annotation-config开启了注解支持时,Spring就会使用AnnotationAwareOrderComparator来进行排序,AnnotationAwareOrderComparator可以支持PriorityOrdered接口、Ordered接口、@Ordered注解、@Priority注解的排序,比较优先级为PriorityOrdered>Ordered>@Ordered>@Priority,而OrderComparator只支持PriorityOrdered、Ordered接口的排序,比较优先级为PriorityOrdered>Ordered,如果最终没找到设置的排序值,那么返回Integer.MAX_VALUE,即最低优先级。@Priority注解属于javax.annotation-api的依赖。
<dependency>
<groupId>javax.annotationgroupId>
<artifactId>javax.annotation-apiartifactId>
<version>1.3.2version>
dependency>
我们此前就讲过,BeanPostProcessor同样作为Spring提供的扩展点。在bean实例化和依赖注入之后,在执行初始化方法前会调用所有BeanPostProcessor 的 postProcessBeforeInitialization 方法,执行初始化方法后会调用所有 BeanPostProcessor 的 postProcessAfterInitialization 方法。当然BeanPostProcessor还有很多不同的实现和扩展,它们的方法也在会在其他地方被回调。
这一步registerBeanPostProcessors方法的目的就是将所有的bean定义中BeanPostProcessor进行实例化和注册,如果给出显式顺序,则按照顺序注册,后续回调的时候也会按照顺序回调。注意这一步并不会回调BeanPostProcessor的方法。如果我们使用BeanFactory作为容器,就不能实现BeanPostProcessor的自动注册,这也是ApplicationContext容器的优点之一。
没有类似addBeanFactoryPostProcessor方法可供我们自定义注册BeanPostProcessor实例。这里的排序的原理和上面的invokeBeanFactoryPostProcessors方法是一样的。
/**
* AbstractApplicationContext的方法
*
* 实例化和注册所有的BeanPostProcessor,如果给出显式顺序,则按照顺序注册。
* 必须在任何应用程序 bean 实例化之前调用
*/
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
//委托给PostProcessorRegistrationDelegate的静态方法registerBeanPostProcessors执行
//传递beanFactory以及当前容器
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
/**
* PostProcessorRegistrationDelegate的静态方法
*
* 实例化和注册所有的BeanPostProcessor,如果给出显式顺序,则按照顺序注册。
*
* @param beanFactory bean工厂
* @param applicationContext 上下文容器
*/
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 从beanFactory中获取所有BeanPostProcessor类型的bean定义的名称数组
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
//beanProcessor的目标计数器
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
//注册一个BeanPostProcessorChecker处理器用
//会在Bean创建完后检查可在当前Bean上起作用的BeanPostProcessor个数与总的BeanPostProcessor个数,如果起作用的个数少于总数,则输出日志信息。
beanFactory.addBeanPostProcessor(new PostProcessorRegistrationDelegate.BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
//这个集合保存实现了PriorityOrdered接口的BeanPostProcessor实例
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
//这个集合保存Spring内部的BeanPostProcessor实例
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
//这个集合保存实现了Ordered接口的BeanPostProcessor的beanName
List<String> orderedPostProcessorNames = new ArrayList<>();
//这个集合保存普通的BeanPostProcessor的beanName
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
//遍历postProcessorNames数组
for (String ppName : postProcessorNames) {
/*如果该名称的bean定义还实现了PriorityOrdered接口,那么初始化*/
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//获取该名称的bean定义的实例,这一步创建了BeanPostProcessor实例
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
//该实例加入到priorityOrderedPostProcessors集合
priorityOrderedPostProcessors.add(pp);
//如果该实例还实现了MergedBeanDefinitionPostProcessor接口
if (pp instanceof MergedBeanDefinitionPostProcessor) {
//该实例加入到internalPostProcessors集合
internalPostProcessors.add(pp);
}
}
/*否则,如果该名称的bean定义还实现了Ordered接口*/
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
//beanName加入到orderedPostProcessorNames集合
orderedPostProcessorNames.add(ppName);
}
/*否则,如果该名称的bean定义即没有实现PriorityOrdered接口也没有实现Ordered接口*/
else {
//beanName加入到nonOrderedPostProcessorNames集合
nonOrderedPostProcessorNames.add(ppName);
}
}
/*
* 对实现了PriorityOrdered接口的BeanPostProcessor实例进行排序,随后按照排序顺序从前向后注册BeanPostProcessor实例
*/
//这里对currentRegistryProcessors集合的元素根据Ordered顺序进行排序
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
//注册给定的BeanPostProcessor
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
//这个集合保存实现了Ordered接口的BeanPostProcessor实例
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
//遍历orderedPostProcessorNames数组
for (String ppName : orderedPostProcessorNames) {
//获取该名称的bean定义的实例,这一步创建了BeanPostProcessor实例
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
//该实例加入到orderedPostProcessors集合
orderedPostProcessors.add(pp);
//如果该实例还实现了MergedBeanDefinitionPostProcessor接口
if (pp instanceof MergedBeanDefinitionPostProcessor) {
//该实例加入到internalPostProcessors集合
internalPostProcessors.add(pp);
}
}
/*
* 对实现了Ordered接口的BeanPostProcessor实例进行排序,随后按照排序顺序从前向后注册BeanPostProcessor实例
*/
//这里对orderedPostProcessors集合的元素根据Ordered顺序进行排序
sortPostProcessors(orderedPostProcessors, beanFactory);
//注册给定的BeanPostProcessor
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
//这个集合保存普通的BeanPostProcessor实例
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
//遍历nonOrderedPostProcessorNames数组
for (String ppName : nonOrderedPostProcessorNames) {
//获取该名称的bean定义的实例,这一步创建了BeanPostProcessor实例
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
//该实例加入到nonOrderedPostProcessors集合
nonOrderedPostProcessors.add(pp);
//如果该实例还实现了MergedBeanDefinitionPostProcessor接口
if (pp instanceof MergedBeanDefinitionPostProcessor) {
//该实例加入到internalPostProcessors集合
internalPostProcessors.add(pp);
}
}
//注册给定的BeanPostProcessor,不需要排序
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
/*
* 对实现了MergedBeanDefinitionPostProcessor接口的Spring内部的BeanPostProcessor实例进行排序,随后按照排序顺序从前向后注册BeanPostProcessor实例
*/
//这里对internalPostProcessors集合的元素根据Ordered顺序进行排序
sortPostProcessors(internalPostProcessors, beanFactory);
//注册给定的BeanPostProcessor,相当于内部的BeanPostProcessor会被移动到处理器集合的尾部
registerBeanPostProcessors(beanFactory, internalPostProcessors);
/*
* 重新注册ApplicationListenerDetector,会被移到处理器集合的末尾
*/
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
registerBeanPostProcessors方法用于将BeanPostProcessor实例按照排序顺序注册到容器中的对应的缓存中去,方便后续的回调操作。
/**
* PostProcessorRegistrationDelegate的方法
*
* 注册给定的BeanPostProcessor
*/
private static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
//循环调用addBeanPostProcessor方法
for (BeanPostProcessor postProcessor : postProcessors) {
beanFactory.addBeanPostProcessor(postProcessor);
}
}
//------AbstractBeanFactory的相关属性
/**
* BeanPostProcessor的缓存集合
*/
private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();
/**
* 指示是否注册了任何InstantiationAwareBeanPostProcessors
* 后面创建bean实例时会用到
*/
private volatile boolean hasInstantiationAwareBeanPostProcessors;
/**
* 指示是否注册了任何DestructionAwareBeanPostProcessors
* 后面创建bean实例时会用到
*/
private volatile boolean hasDestructionAwareBeanPostProcessors;
/**
* AbstractBeanFactory的方法
*
* 注册beanPostProcessor到AbstractBeanFactory内部的缓存中
*
* @param beanPostProcessor bean后处理器实例
*/
@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
// 移除旧的beanPostProcessor(如果存在),主要是为了保证顺序
this.beanPostProcessors.remove(beanPostProcessor);
// Track whether it is instantiation/destruction aware
//如果当前beanPostProcessor实例还实现了InstantiationAwareBeanPostProcessor接口
if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
//那么hasInstantiationAwareBeanPostProcessors属性置为true
this.hasInstantiationAwareBeanPostProcessors = true;
}
//如果当前beanPostProcessor实例还实现了DestructionAwareBeanPostProcessor接口
if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
//那么hasDestructionAwareBeanPostProcessors属性置为true
this.hasDestructionAwareBeanPostProcessors = true;
}
//添加到beanPostProcessors集合缓存末尾
this.beanPostProcessors.add(beanPostProcessor);
}
initMessageSource用于初始化消息资源 MessageSource,用于语言国际化处理,如果没有配置自定义的MessageSource,那么默认使用DelegatingMessageSource实例。
国际化是什么意思?就是说如果我们需要开发一个支持多国语言的应用程序,要求系统能够根据客户端的系统的语言类型返回对应的界面,此时就需要用到i18n国际化操作,它可以根据不同地方的语言环境自动返回不同语言的页面。
一般来说用的本地公司比较少,可能对于有跨国业务的公司或者大公司来说这一项功能用的比较多,后续有时间有机会再单独讲解。
//-----AbstractApplicationContext的相关属性
/**
*
* 硬编码的指定工厂中的MessageSource bean 的名称
*/
public static final String MESSAGE_SOURCE_BEAN_NAME = "messageSource";
/**
* 消息源
*/
@Nullable
private MessageSource messageSource;
/**
* 父上下文容器
*/
@Nullable
private ApplicationContext parent;
/**
* AbstractApplicationContext的方法
*
* 初始化消息资源 MessageSource,用于语言国际化处理
* 如果没有配置自定义的MessageSource,那么默认使用DelegatingMessageSource实例
*/
protected void initMessageSource() {
//获取beanFactory
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//本地工厂(忽略父工厂)如果包含名为"messageSource"的bean定义
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
//如果已经配置了messageSource的bean定义,那么将messageSource初始化并且赋给messageSource属性
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
//如果父上下文容器不为null并且当前消息源实现了HierarchicalMessageSource接口,一般不会走到这一步,一般父容器都为null
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
//那么设置当前消息源的父消息源
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
if (logger.isTraceEnabled()) {
logger.trace("Using MessageSource [" + this.messageSource + "]");
}
}
/*否则,使用DelegatingMessageSource实例作为消息资源*/
else {
//新建一个DelegatingMessageSource实例
DelegatingMessageSource dms = new DelegatingMessageSource();
//设置当前消息源的父消息源
dms.setParentMessageSource(getInternalParentMessageSource());
//将messageSource实例赋给messageSource属性
this.messageSource = dms;
//手动注册一个名为"messageSource"的单例bean实例
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
if (logger.isTraceEnabled()) {
logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
}
}
}
/**
* 如果父上下文也是抽象应用程序上下文(AbstractApplicationContext),则返回其内部的消息源,否则,返回父上下文本身。
*/
@Nullable
protected MessageSource getInternalParentMessageSource() {
return (getParent() instanceof AbstractApplicationContext ?
((AbstractApplicationContext) getParent()).messageSource : getParent());
}
initApplicationEventMulticaster用于初始化ApplicationEventMulticaster,即应用事件广播器。和MessageSource的初始化过程一样,如果用户自定义了应用事件广播器,那么使用用户自定义的,否则默认使用SimpleApplicationEventMulticaster作为应用事件广播器。
应用事件广播器的功能也很直白,就是进行ApplicationContext事件广播。当产生某一个ApplicationContext事件的时候,会将该事件委托广播器调用multicastEvent方法,就像一个广播一样通知广播器内部保存的所有监听器,遍历并对每一个监听器调用listener.onApplicationEvent方法传递该事件,而后续的事件处理则是由每一个监听器自己的内部逻辑决定的。
/*AbstractApplicationContext的属性*/
/**
* 硬编码指定的beanFactory中的自定义ApplicationEventMulticaster 的beanName
* 如果未提供自定义的广播器,则使用默认的SimpleApplicationEventMulticaster
*/
public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster";
/**
* 保存事件发布中使用的帮助器类
*/
@Nullable
private ApplicationEventMulticaster applicationEventMulticaster;
/**
* AbstractApplicationContext的方法
*
* 初始化应用程序事件广播器。 如果自己没有指定广播器,则使用SimpleApplicationEventMulticaster。
*/
protected void initApplicationEventMulticaster() {
//获取beanFactory
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
/*
* 本地工厂(忽略父工厂),如果包含名为"applicationEventMulticaster"的bean定义
*/
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
//那么将该beanName的bean定义作为ApplicationEventMulticaster类型尝试初始化并赋给applicationEventMulticaster属性
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isTraceEnabled()) {
logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
/*
* 否则,使用SimpleApplicationEventMulticaster实例作为广播器
*/
else {
//新建一个SimpleApplicationEventMulticaster实例,赋给applicationEventMulticaster属性
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
//将初始化的广播器手动注册为一个名为"applicationEventMulticaster"的单例bean实例,因此我们在Spring管理的bean中也可以引入该对象
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isTraceEnabled()) {
logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
}
}
}
onRefresh方法默认是一个空的实现,这是留给子类容器实现的模版方法。子类容器可以重写用于添加特定的上下文的刷新工作,比如在普通单例bean实例化之前,进行特殊bean的初始化。非web应用中该方法没有实现,web应用中某些子类则会重写该方法。
/**
* AbstractApplicationContext的方法
* 子类容器可以重写用于添加特定的上下文的刷新工作的模版方法,比如在普通单例bean实例化之前,进行特殊bean的初始化。
*/
protected void onRefresh() throws BeansException {
// 默认空实现
}
registerListeners方法用于实例化并注册所有的Listener,即监听器。监听器的来源有两个:一个是调用addApplicationListener方法手动添加的listener,它们被添加到AbstractApplicationContext的applicationListeners集合中,另一个就是添加的ApplicationListener类型的普通bean定义,在registerListeners方法中会从beanFactory中找出所有的ApplicationListener类型的bean定义并初始化。
注册所有监听器之后会发布所有的早期的应用程序事件,非web应用默认没有早期事件。
/**
* AbstractApplicationContext的方法
*
* 实例化并注册监听器到应用事件广播器中,随后发布早期应用程序事件
*/
protected void registerListeners() {
/*
* 首先注册手动添加的监听器
* 手动添加就是调用addApplicationListener方法添加的listener,它们被放入applicationListeners集合
*/
for (ApplicationListener<?> listener : getApplicationListeners()) {
//注册到ApplicationEventMulticaster中
getApplicationEventMulticaster().addApplicationListener(listener);
}
/*
* 随后将beanFactory中的所有ApplicationListener类型的bean定义初始化并注册
*/
//从beanFactory中获取所有ApplicationListener类型的bean定义的名称数组
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
//遍历listenerBeanNames数组
for (String listenerBeanName : listenerBeanNames) {
//注册到ApplicationEventMulticaster中
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
/*
* 通过应用程序广播器对注册的监听器发布所有收集的早期应用程序事件
* earlyApplicationEvents默认就是空集合
*/
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
//earlyApplicationEvents置为null
this.earlyApplicationEvents = null;
if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
//调用multicastEvent方法按照遍历顺序发布应用程序事件
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
//--------AbstractApplicationContext的相关属性
/**
* 调用addApplicationListener方法添加的listener监听器集合
*/
private final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();
/**
* 在广播器和监听器被设置之前发布的应用程序事件,被收集到该集合中
*/
@Nullable
private Set<ApplicationEvent> earlyApplicationEvents;
/**
* 应用事件广播器,在前面的initApplicationEventMulticaster方法中已经初始化了
*/
@Nullable
private ApplicationEventMulticaster applicationEventMulticaster;
/**
* AbstractApplicationContext的方法
*
* 返回监听器集合
*/
public Collection<ApplicationListener<?>> getApplicationListeners() {
return this.applicationListeners;
}
/**
1. AbstractApplicationContext的方法
2.
3. 返回上下文容器中使用的applicationEventMulticaster,不能为null
*/
ApplicationEventMulticaster getApplicationEventMulticaster() throws IllegalStateException {
if (this.applicationEventMulticaster == null) {
throw new IllegalStateException("ApplicationEventMulticaster not initialized - " +
"call 'refresh' before multicasting events via the context: " + this);
}
return this.applicationEventMulticaster;
}
本次我们学习了refresh()方法内部的obtainFreshBeanFactory——加载bean定义和finishBeanFactoryInitialization——完成bean初始化这两个方法之间
的全部流程,概括起来就是:
prepareBeanFactory
:对新获取的BeanFactory进行一系列配置,这也是applicationContext功能的扩展。postProcessBeanFactory
:默认是一个空的实现,这是留给子类容器实现对beanFactory后续处理的扩展方法。invokeBeanFactoryPostProcessors
:实例化所有BeanFactoryPostProcessor(包括其子类 BeanDefinitionRegistryPostProcessor)后处理器并按照一定的顺序调用相应的postProcessBeanDefinitionRegistry和postProcessBeanFactory回调方法,此时所有 bean 定义——beanDefinition都将已加载,但尚未实例化任何普通 bean。这允许我们重写beanDefinition或添加beanDefinition,修改beanFactory中的beanDefinition的任何可以修改的地方。
ConfigurationClassPostProcessor
后处理器,就是BeanDefinitionRegistryPostProcessor的实例,就会在此时回调postProcessBeanDefinitionRegistry方法,用于解析配置类以及各种配置注解@Configuration 、@Component、@ComponentScan、@Import、@ImportResource……,@Bean注解也是在这里解析的,解析的bean定义会被注册到注册表中!PropertySourcesPlaceholderConfigurer
后处理器,就是BeanFactoryPostProcessor的实例,就会在此时回调postProcessBeanFactory方法,先把environment和本地localProperties属性源放到内部的PropertySources集合中,随后用于解析bean定义中的属性值中的占位符,替换为真实值!后续还被用于解析@Resource、@Value等注解的值中的占位符解析、替换为真实值!这些后处理器的扩展内容后面单独讲解!
registerBeanPostProcessors
:实例化和注册所有BeanPostProcessor后处理器,方便后续创建bean实例的时候的回调方法调用,这一步并没有进行回调方法调用。initMessageSource
:为此上下文容器初始化MessageSource消息资源,用于语言国际化处理。initApplicationEventMulticaster
:为此上下文容器初始化事件广播器,应用事件广播。onRefresh
:默认是一个空的实现,这是留给子类容器实现的扩展方法。registerListeners
:实例化和注册所有Listener监听器。我们还学习了很多扩展点:BeanPostProcessor后处理器、忽略setter自动注入、指定自动注入实例、手动注册单例bean、 postProcessBeanFactory方法、BeanFactoryPostProcessor后处理器扩展点(postProcessBeanFactory方法)、BeanDefinitionRegistryPostProcessor后处理器扩展点(postProcessBeanFactory和postProcessBeanDefinitionRegistry方法)、onRefresh方法等等。
本文只是讲解了容器初始化的大概调用过程,并没有针对某个知识点进行讲解。在后面的文章中我们会对比如< import/>标签的解析、< alias/>标签的解析、< context:property-placeholder/>扩展标签的解析,PropertySourcesPlaceholderConfigurer、ConfigurationClassPostProcessor等一批后处理器的工作原理等一些重要的知识点进行单独解析。
相关文章:
https://spring.io/
Spring Framework 5.x 学习
Spring Framework 5.x 源码
如有需要交流,或者文章有误,请直接留言。另外希望点赞、收藏、关注,我将不间断更新各种Java学习博客!