1 前言
spring提供了一个接口ApplicationContext,其作用和BeanFactory一样,都是用于加载bean。比如我们在测试类中启动spring的时候,常见的AnnotationConfigApplicationContext类,就实现了这个接口。在我个人目前的理解中,ApplicationContext可以指代spring容器。所以,容器的创建过程,就是创建一个ApplicationContext的过程。
本文大部分内容都是参考了《spring 源码深度解析》一书,喜欢的可以买来看看!
2 容器的创建概览
2.1 创建的入口
这里放一个普通的spring测试类,代码如下:
@Test
public void test1(){
ApplicationContext app = new AnnotationConfigApplicationContext(配置类.class);
}
这段代码的含义,就是创建spring容器,只不过是需要从配置类中加载配置。进入这个构造方法,其代码如下:
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
this.register(annotatedClasses);
this.refresh();
}
这里的重头戏,便是**this.refresh()**方法了,在它里面完成了ApplicationContext几乎所有的功能。而且这一段代码写的很优秀,值得反复琢磨。这也是我学源码的时候很喜欢的一段了,逻辑很清晰,没有那种突然一大段代码扑到脸上的不知所措感,虽然刚开始看的时候根本不知道每个方法都在搞什么。
2.2 refresh()方法源码
refresh()方法源码和每个方法的注释如下:
public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {
//准备刷新的上下文环境
this.prepareRefresh();
//初始化BeanFactory,并且读取配置
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
//对BeanFactory做功能的补充和完善
this.prepareBeanFactory(beanFactory);
try {
//留给子类去扩展的
this.postProcessBeanFactory(beanFactory);
//注册和调用BeanFactoryPostProcessor,从而对BeanFactory做后置处理
this.invokeBeanFactoryPostProcessors(beanFactory);
//注册BeanPostProcessor,注意仅仅是注册,而且是用来处理Bean的
this.registerBeanPostProcessors(beanFactory);
//为上下文初始化Message源,即不同语言的消息体,国际化处理
this.initMessageSource();
//初始化广播器
this.initApplicationEventMulticaster();
//留给子类重写,来初始化其他的bean。springboot内置的tomcat启动就和这个方法有关
this.onRefresh();
//从所有bean中找出Listener,并注册到广播器
this.registerListeners();
//初始化非懒加载的单例bean
this.finishBeanFactoryInitialization(beanFactory);
//完成刷新
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}
3 详细分析
3.1 prepareRefresh()
主要做环境准备工作,比如系统的属性或者环境的验证和初始化工作。源码如下:
protected void prepareRefresh() {
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
if (this.logger.isInfoEnabled()) {
this.logger.info("Refreshing " + this);
}
//留给子类重写的
this.initPropertySources();
//验证环境中是否有需要的属性或配置
this.getEnvironment().validateRequiredProperties();
this.earlyApplicationEvents = new LinkedHashSet();
}
3.2 obtainFreshBeanFactory():获取BeanFactory,加载配置
方法名直译过来,获得新鲜的BeanFactory。其实就是对BeanFactory进行创建,刚刚创建,所以比较新鲜。
源码如下:
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
//初始化BeanFactory,读取配置,并将BeanFactory保存在当前类的属性中
this.refreshBeanFactory();
//从当前类的属性中拿到BeanFactory
ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
if (this.logger.isDebugEnabled()) {
this.logger.debug("Bean factory for " + this.getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
在以上代码中,核心部分是refreshBeanFactory。
重写refreshBeanFactory方法的子类有两个,AbstractRefreshableApplicationContext和GenericApplicationContext。
在new AnnotationConfigApplicationContext(配置类.class)时,由于启动类AnnotationConfigApplicationContext继承的是GenericApplicationContext,所以如果跑的是最上面的示例测试类时,运行的是GenericApplicationContext重写的refreshBeanFactory。
但是由于GenericApplicationContext重写的方法很简单,即直接反序列化得到BeanFactory对象,所以这里看的是AbstractRefreshableApplicationContext中重写的方法,这里较为详细,可以学到更多spring源码的精髓。
这里进入其子类AbstractRefreshableApplicationContext中重写的方法中看看。其源码如下
protected final void refreshBeanFactory() throws BeansException {
if (this.hasBeanFactory()) {
this.destroyBeans();
this.closeBeanFactory();
}
try {
//创建DefaultListableBeanFactory
DefaultListableBeanFactory beanFactory = this.createBeanFactory();
//指定序列化id,如果需要,给以反序列化得到DefaultListableBeanFactory
beanFactory.setSerializationId(this.getId());
//定制BeanFactory
this.customizeBeanFactory(beanFactory);
//加载配置
this.loadBeanDefinitions(beanFactory);
synchronized(this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
} catch (IOException var5) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var5);
}
}
从上面这段源码来看,其实其主要工作就三步,1 创建BeanFactory,2 定制BeanFactory,3 加载配置。
3.2.1 创建BeanFactory
protected DefaultListableBeanFactory createBeanFactory() {
return new DefaultListableBeanFactory(this.getInternalParentBeanFactory());
}
其实就是简单的调用了构造方法。
3.2.2 定制BeanFactory
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
if (this.allowBeanDefinitionOverriding != null) {
beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
//是否允许循环依赖
if (this.allowCircularReferences != null) {
beanFactory.setAllowCircularReferences(this.allowCircularReferences);
}
}
3.2.3 加载配置
加载配置文件,需要两个类,分别是DefaultListableBeanFactory 和 XmlBeanDefinitionReader,前者已经在3.2.1创建BeanFactory时拿到了,在前面createBeanFactory方法中已经创建了,那么就需要生成后者。
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
//利用DefaultListableBeanFactory 生成 XmlBeanDefinitionReader
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
this.initBeanDefinitionReader(beanDefinitionReader);
//加载配置文件
this.loadBeanDefinitions(beanDefinitionReader);
}
通过上面的操作,此时容器中已经解析了所有的配置。
3.3 prepareBeanFactory(beanFactory):BeanFactory的功能扩展
解析完了配置,创建了BeanFactory,接下来就是对BeanFactory的完善了。其源码如下:
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
beanFactory.setBeanClassLoader(this.getClassLoader());
//设置表达式解析器,这里的表达式就是 #{xxxx.xxx}
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
//增加PropertyEditor,对bean的属性进行设置,PropertyEditor可以理解为一种转换器,比如对Date的转换器,部分就在这里添加
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));
//添加BeanPostProcessor
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//设置几个忽略自动装配的接口
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
//设置几个特殊装配的接口
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
//添加BeanPostProcessor
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
//对AspectJ的支持
if (beanFactory.containsBean("loadTimeWeaver")) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
//添加默认的系统环境bean
if (!beanFactory.containsLocalBean("environment")) {
beanFactory.registerSingleton("environment", this.getEnvironment());
}
if (!beanFactory.containsLocalBean("systemProperties")) {
beanFactory.registerSingleton("systemProperties", this.getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean("systemEnvironment")) {
beanFactory.registerSingleton("systemEnvironment", this.getEnvironment().getSystemEnvironment());
}
}
3.3.1 spEL的支持
spEL,全称spring expression language。
spEL用法:#{xxx.xxx},例如#{person.name}。实际上spEL的用法有很多,而且很灵活,具体用法可以参考如下链接:
注意:spEL中,#{}没有从properties中读取值的功能。${}才可以从properties中读取值,而且对于mybatis,不能防止sql注入,因为在mybatis中其作用为直接替换,不会解析,而是直接注入。#{}会进行解析,可以防止sql注入。
3.3.2 增加属性编辑器
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));
spring在依赖注入的时候,有些属性其实并不能注入,常见的类型比如Date类型的属性,直接注入类似“2021-1-1”这样的日期,会报错。所以需要自定义属性编辑器。我们自己写的属性编辑器,和spring自带的属性编辑器,都会在这里被添加。
可以看一下被添加进BeanFactory的ResourceEditorRegistrar中的registerCustomEditors方法,如下所示,就是注册很多属性编辑器罢了。
public void registerCustomEditors(PropertyEditorRegistry registry) {
ResourceEditor baseEditor = new ResourceEditor(this.resourceLoader, this.propertyResolver);
this.doRegisterEditor(registry, Resource.class, baseEditor);
this.doRegisterEditor(registry, ContextResource.class, baseEditor);
this.doRegisterEditor(registry, InputStream.class, new InputStreamEditor(baseEditor));
this.doRegisterEditor(registry, InputSource.class, new InputSourceEditor(baseEditor));
this.doRegisterEditor(registry, File.class, new FileEditor(baseEditor));
this.doRegisterEditor(registry, Path.class, new PathEditor(baseEditor));
this.doRegisterEditor(registry, Reader.class, new ReaderEditor(baseEditor));
this.doRegisterEditor(registry, URL.class, new URLEditor(baseEditor));
ClassLoader classLoader = this.resourceLoader.getClassLoader();
this.doRegisterEditor(registry, URI.class, new URIEditor(classLoader));
this.doRegisterEditor(registry, Class.class, new ClassEditor(classLoader));
this.doRegisterEditor(registry, Class[].class, new ClassArrayEditor(classLoader));
if (this.resourceLoader instanceof ResourcePatternResolver) {
this.doRegisterEditor(registry, Resource[].class, new ResourceArrayPropertyEditor((ResourcePatternResolver)this.resourceLoader, this.propertyResolver));
}
}
这里提个问,registerCustomEditors才是注册属性编辑器的方法,但是添加进BeanFactory的时候,没有调用registerCustomEditors,那么该方法在哪调用?
答:在如下方法中被调用。
protected void initBeanWrapper(BeanWrapper bw) {
bw.setConversionService(this.getConversionService());
this.registerCustomEditors(bw);
}
而initBeanWrapper----》被instantiateBean调用,instantiateBean—》被createBeanInstance调用,createBeanInstance—》被doCreateBean调用。
那么这里就显而易见了,这些属性编辑器,就是在实例化bean的时候注册的。
那么又有疑问,有没有觉得这里注册的属性编辑器还不够多呢,我们常用的Integer、Long等,好像并没有出现?
答:对于一个BeanWrapper,spring默认的实现为BeanWrapperImpl,而BeanWrapperImpl继承了PropertyEditorRegistrySupport。这个PropertyEditorRegistrySupport有个方法,如下所示:
private void createDefaultEditors() {
this.defaultEditors = new HashMap(64);
this.defaultEditors.put(Charset.class, new CharsetEditor());
this.defaultEditors.put(Class.class, new ClassEditor());
this.defaultEditors.put(Class[].class, new ClassArrayEditor());
this.defaultEditors.put(Currency.class, new CurrencyEditor());
this.defaultEditors.put(File.class, new FileEditor());
this.defaultEditors.put(InputStream.class, new InputStreamEditor());
this.defaultEditors.put(InputSource.class, new InputSourceEditor());
this.defaultEditors.put(Locale.class, new LocaleEditor());
this.defaultEditors.put(Path.class, new PathEditor());
this.defaultEditors.put(Pattern.class, new PatternEditor());
this.defaultEditors.put(Properties.class, new PropertiesEditor());
this.defaultEditors.put(Reader.class, new ReaderEditor());
this.defaultEditors.put(Resource[].class, new ResourceArrayPropertyEditor());
this.defaultEditors.put(TimeZone.class, new TimeZoneEditor());
this.defaultEditors.put(URI.class, new URIEditor());
this.defaultEditors.put(URL.class, new URLEditor());
this.defaultEditors.put(UUID.class, new UUIDEditor());
this.defaultEditors.put(ZoneId.class, new ZoneIdEditor());
this.defaultEditors.put(Collection.class, new CustomCollectionEditor(Collection.class));
this.defaultEditors.put(Set.class, new CustomCollectionEditor(Set.class));
this.defaultEditors.put(SortedSet.class, new CustomCollectionEditor(SortedSet.class));
this.defaultEditors.put(List.class, new CustomCollectionEditor(List.class));
this.defaultEditors.put(SortedMap.class, new CustomMapEditor(SortedMap.class));
this.defaultEditors.put(byte[].class, new ByteArrayPropertyEditor());
this.defaultEditors.put(char[].class, new CharArrayPropertyEditor());
this.defaultEditors.put(Character.TYPE, new CharacterEditor(false));
this.defaultEditors.put(Character.class, new CharacterEditor(true));
this.defaultEditors.put(Boolean.TYPE, new CustomBooleanEditor(false));
this.defaultEditors.put(Boolean.class, new CustomBooleanEditor(true));
this.defaultEditors.put(Byte.TYPE, new CustomNumberEditor(Byte.class, false));
this.defaultEditors.put(Byte.class, new CustomNumberEditor(Byte.class, true));
this.defaultEditors.put(Short.TYPE, new CustomNumberEditor(Short.class, false));
this.defaultEditors.put(Short.class, new CustomNumberEditor(Short.class, true));
this.defaultEditors.put(Integer.TYPE, new CustomNumberEditor(Integer.class, false));
this.defaultEditors.put(Integer.class, new CustomNumberEditor(Integer.class, true));
this.defaultEditors.put(Long.TYPE, new CustomNumberEditor(Long.class, false));
this.defaultEditors.put(Long.class, new CustomNumberEditor(Long.class, true));
this.defaultEditors.put(Float.TYPE, new CustomNumberEditor(Float.class, false));
this.defaultEditors.put(Float.class, new CustomNumberEditor(Float.class, true));
this.defaultEditors.put(Double.TYPE, new CustomNumberEditor(Double.class, false));
this.defaultEditors.put(Double.class, new CustomNumberEditor(Double.class, true));
this.defaultEditors.put(BigDecimal.class, new CustomNumberEditor(BigDecimal.class, true));
this.defaultEditors.put(BigInteger.class, new CustomNumberEditor(BigInteger.class, true));
if (this.configValueEditorsActive) {
StringArrayPropertyEditor sae = new StringArrayPropertyEditor();
this.defaultEditors.put(String[].class, sae);
this.defaultEditors.put(short[].class, sae);
this.defaultEditors.put(int[].class, sae);
this.defaultEditors.put(long[].class, sae);
}
}
不管这个方法在哪调用的,至少知道了spring确实定义了很多属性编辑器。像Date类型,上面就没有,所以需要自己自定义。
3.3.3 添加ApplicationContextAwareProcessor处理器
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
其实在prepareBeanFactory中,就是单纯地把ApplicationContextAwareProcessor注册为BeanPostProcessor后置处理器。但是ApplicationContextAwareProcessor本身是一个很有作用处理器。
先看下这个类的继承和实现关系:
class ApplicationContextAwareProcessor implements BeanPostProcessor
既然实现了BeanPostProcessor,必然实现了BeanPostProcessor中的抽象方法,具体如下:
@Nullable
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
AccessControlContext acc = null;
if (System.getSecurityManager() != null && (bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware || bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware || bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}
if (acc != null) {
AccessController.doPrivileged(() -> {
this.invokeAwareInterfaces(bean);
return null;
}, acc);
} else {
this.invokeAwareInterfaces(bean);
}
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) {
return bean;
}
从源码来看,重点就是postProcessBeforeInitialization方法。可以看到,方法中调用了invokeAwareInterfaces,跟进invokeAwareInterfaces中看到源码如下:
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof Aware) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware)bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware)bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware)bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware)bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware)bean).setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware)bean).setApplicationContext(this.applicationContext);
}
}
}
可以看到方法里进行了类似switch似的的判断,如果满足条件则将某种功能赋予这个bean中。
再多留意一下可以发现,这些条件判断里的接口,都是***Aware这种格式。在spring中,以Aware结尾的接口,其作用是给bean中添加一些容器中的资源,例如:
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware)bean).setApplicationContext(this.applicationContext);
}
就是给bean中注入spring容器。
3.3.4 设置依赖忽略
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
为什么要设置忽略依赖?
首先,可以看出,这里忽略的,正是invokeAwareInterfaces()中出现的接口。
因为在3.3.3中invokeAwareInterfaces()方法中出现的这个接口,已经不能算作一个普通bean了。需要实现这些接口才可以使用接口提供的功能,而不是通过依赖注入的方式。
3.3.5 注册依赖
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
与依赖忽略相反,依赖注册是当解析到bean需要注入以上这些类型的依赖时,便会将其注入。
3.4 invokeBeanFactoryPostProcessors(beanFactory):注册并激活BeanFactoryPostProcessor
源码如下:
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
//注册并激活BeanFactoryPostProcessor
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors());
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean("loadTimeWeaver")) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
3.4.1 BeanFactoryPostProcessor的典型应用----》PropertyPlaceholderConfigurer
在dubbo项目中,可能会看到如下配置:
<dubbo:protocol host="${dubbo.ip}" name="dubbo" port="20886" />
不管这个duboo标签的意义是什么,单说${dubbo.ip},其意义就是去配置文件中读取dubbo.ip对应的值。在配置文件中,存在如下内容:
dubbo.ip=127.0.0.1
但是这里仍有问题,那就是spring怎么知道这里存在着待解析的配置文件呢?----》PropertyPlaceholderConfigurer
如下为PropertyPlaceholderConfigurer在配置文件中的配置方式:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:props/test1.properties</value>
<value>classpath:props/test11.properties</value>
<value>classpath:props/test111.properties</value>
<value>classpath:props/test1111.properties</value>
</list>
</property>
</bean>
这样便解决了上述问题。
PropertyPlaceholderConfigurer和BeanFactoryPostProcessor是什么关系呢?
这个关系其实蛮好找到,就是PropertyPlaceholderConfigurer实现了BeanFactoryPostProcessor接口。
这个接口长这样:
public interface BeanFactoryPostProcessor {
void postProcessBeanFactory(ConfigurableListableBeanFactory var1) throws BeansException;
}
也就是说PropertyPlaceholderConfigurer实现了postProcessBeanFactory方法。
可是从配置来看,作为一个普通的bean,并没有被其他bean调用,那么spring怎么知道要在这个bean中有配置文件的信息呢?
因为其实现了BeanFactoryPostProcessor接口。
可以看下PropertyPlaceholderConfigurer的父类PropertyResourceConfigurer中实现的postProcessBeanFactory方法源码:
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
try {
Properties mergedProps = this.mergeProperties();
this.convertProperties(mergedProps);
this.processProperties(beanFactory, mergedProps);
} catch (IOException var3) {
throw new BeanInitializationException("Could not load properties", var3);
}
}
总结一下,这里做了三件事:
1 得到配置;
2 将得到的配置转换为适当的类型;
3 将配置告知beanFactory;
所以以上这个问题的答案就是,PropertyPlaceholderConfigurer作为一个BeanFactory的后置处理器,其重写的postProcessBeanFactory方法完成了从配置中读取配置文件信息的功能。
3.4.2 激活BeanFactoryPostProcessor
源码很长,但是仍有规律可循。以下为注释版源码:
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
Set<String> processedBeans = new HashSet();
int var9;
ArrayList currentRegistryProcessors;
String[] postProcessorNames;
//对实现了BeanDefinitionRegistry的beanFactory的处理
//顺带一提,spring默认的DefaultListableBeanFactory就实现了BeanDefinitionRegistry接口
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry)beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList();
//拿到硬编码的beanFactoryPostProcessors
Iterator var6 = beanFactoryPostProcessors.iterator();
while(var6.hasNext()) {
BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var6.next();
//判断后置处理器是否实现了BeanDefinitionRegistryPostProcessor接口
//BeanDefinitionRegistryPostProcessor接口和BeanFactoryPostProcessor什么关系?如下所示:
//public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor)postProcessor;
//调用硬编码的BeanDefinitionRegistryPostProcessor类型处理器中的postProcessBeanDefinitionRegistry方法
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
} else {
//记录硬编码的常规BeanFactoryPostProcessor
regularPostProcessors.add(postProcessor);
}
}
currentRegistryProcessors = new ArrayList();
//从配置里拿BeanDefinitionRegistryPostProcessor
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
String[] var18 = postProcessorNames;
var9 = postProcessorNames.length;
//根据PriorityOrdered筛选从配置中拿到的BeanDefinitionRegistryPostProcessor,并放入currentRegistryProcessors
int var10;
String ppName;
for(var10 = 0; var10 < var9; ++var10) {
ppName = var18[var10];
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
//激活BeanDefinitionRegistryPostProcessor中的postProcessBeanDefinitionRegistry方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//清空currentRegistryProcessors中的BeanDefinitionRegistryPostProcessor
currentRegistryProcessors.clear();
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
var18 = postProcessorNames;
var9 = postProcessorNames.length;
//根据Ordered筛选从配置中拿到的BeanDefinitionRegistryPostProcessor,并放入currentRegistryProcessors
for(var10 = 0; var10 < var9; ++var10) {
ppName = var18[var10];
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
//激活BeanDefinitionRegistryPostProcessor中的postProcessBeanDefinitionRegistry方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//清空currentRegistryProcessors中的BeanDefinitionRegistryPostProcessor
currentRegistryProcessors.clear();
boolean reiterate = true;
while(reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
String[] var21 = postProcessorNames;
var10 = postProcessorNames.length;
//处理其余的从配置中拿到的BeanDefinitionRegistryPostProcessor,并放入currentRegistryProcessors
for(int var28 = 0; var28 < var10; ++var28) {
String ppName = var21[var28];
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
//激活BeanDefinitionRegistryPostProcessor中的postProcessBeanDefinitionRegistry方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//清空currentRegistryProcessors中的BeanDefinitionRegistryPostProcessor
currentRegistryProcessors.clear();
}
//激活在**硬编码和配置**中,实现了**BeanDefinitionRegistryPostProcessor**的处理器中的postProcessBeanFactory方法,因为BeanDefinitionRegistryPostProcessor接口继承了BeanFactoryPostProcessor接口
invokeBeanFactoryPostProcessors((Collection)registryProcessors, (ConfigurableListableBeanFactory)beanFactory);
//激活**硬编码**中,实现了**BeanFactoryPostProcessor**的类中的postProcessBeanFactory方法
invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
} else {
invokeBeanFactoryPostProcessors((Collection)beanFactoryPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
}
//从**配置**中拿到实现了BeanFactoryPostProcessor接口的类
//类似上面的结构,根据PriorityOrdered和Ordered筛选,然后调用其postProcessBeanFactory方法
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList();
List<String> orderedPostProcessorNames = new ArrayList();
currentRegistryProcessors = new ArrayList();
postProcessorNames = postProcessorNames;
int var22 = postProcessorNames.length;
String ppName;
for(var9 = 0; var9 < var22; ++var9) {
ppName = postProcessorNames[var9];
if (!processedBeans.contains(ppName)) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
} else {
currentRegistryProcessors.add(ppName);
}
}
}
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors((Collection)priorityOrderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList();
Iterator var23 = orderedPostProcessorNames.iterator();
while(var23.hasNext()) {
String postProcessorName = (String)var23.next();
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors((Collection)orderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList();
Iterator var26 = currentRegistryProcessors.iterator();
while(var26.hasNext()) {
ppName = (String)var26.next();
nonOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors((Collection)nonOrderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
beanFactory.clearMetadataCache();
}
代码很长,其实最重要的就是做两件事:
1 对实现了BeanDefinitionRegistry的beanFactory的处理;
2 对普通BeanFactoryPostProcessor的处理;
3.4.2.1 对实现了BeanDefinitionRegistry的beanFactory的处理
这一过程中主要处理的是实现了BeanDefinitionRegistryPostProcessor接口的类,和硬编码的实现了BeanFactoryPostProcessor的类。处理的类型分以下几种情况:
1 硬编码方式注册的BeanDefinitionRegistryPostProcessor处理器;
2 硬编码方法注册的BeanFactoryPostProcessor处理器;
3 通过配置方式注册的BeanDefinitionRegistryPostProcessor处理器;
这里介绍下BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor的关系哈。如下:
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry var1) throws BeansException;
}
@FunctionalInterface
public interface BeanFactoryPostProcessor {
void postProcessBeanFactory(ConfigurableListableBeanFactory var1) throws BeansException;
}
3.4.2.2 对普通BeanFactoryPostProcessor的处理
见源码注释。
可以从源码中看到,硬编码方式添加的后置处理器不需要排序,但是通过配置得到的处理器需要排序。spring为了保证排序顺序,用PriorityOrdered和Ordered保证了顺序调用。
3.5 registerBeanPostProcessors(beanFactory):注册BeanPostProcessor处理器
3.5.1 BeanPostProcessor接口的作用介绍
接口源码如下:
public interface BeanPostProcessor {
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
回顾之前说的bean的加载过程,在bean初始化时,执行了如下代码:
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(() -> {
this.invokeAwareMethods(beanName, bean);
return null;
}, this.getAccessControlContext());
} else {
this.invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
}
try {
this.invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable var6) {
throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
其中,在
wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
和
wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
中就对实现了BeanPostProcessor接口的类重写的postProcessBeforeInitialization和postProcessAfterInitialization方法进行了调用。
3.5.2 registerBeanPostProcessors(beanFactory)源码分析
首先得强调一下,registerBeanPostProcessors只是把BeanPostProcessor注册,而不是激活或者调用。激活是在getBean的时候,上面3.5.1中提到的初始化initializeBean()才是调用它的地方。
源码如下:
public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new PostProcessorRegistrationDelegate.BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
//四种存放BeanPostProcessor的缓存
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList();
List<BeanPostProcessor> internalPostProcessors = new ArrayList();
List<String> orderedPostProcessorNames = new ArrayList(); //这里注意是String类型
List<String> nonOrderedPostProcessorNames = new ArrayList(); //这里注意是String类型
String[] var8 = postProcessorNames;
int var9 = postProcessorNames.length;
String ppName;
BeanPostProcessor pp;
//根据PriorityOrdered、Ordered进行筛选
for(int var10 = 0; var10 < var9; ++var10) {
ppName = var8[var10];
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
} else {
nonOrderedPostProcessorNames.add(ppName);
}
}
//注册实现了PriorityOrdered接口的BeanPostProcessor
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, (List)priorityOrderedPostProcessors);
List<BeanPostProcessor> orderedPostProcessors = new ArrayList();
Iterator var14 = orderedPostProcessorNames.iterator();
//因为存放实现了Ordered的接口的处理器的缓存为List<String> orderedPostProcessorNames,需要从name--》BeanPostProcessor
while(var14.hasNext()) {
String ppName = (String)var14.next();
BeanPostProcessor pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
//注册实现了Ordered接口的BeanPostProcessor
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, (List)orderedPostProcessors);
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList();
Iterator var17 = nonOrderedPostProcessorNames.iterator();
//因为存放不优先的处理器的缓存为 List<String> nonOrderedPostProcessorNames,需要从name--》BeanPostProcessor
while(var17.hasNext()) {
ppName = (String)var17.next();
pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
//注册未实现PriorityOrdered和Ordered接口的BeanPostProcessor
registerBeanPostProcessors(beanFactory, (List)nonOrderedPostProcessors);
sortPostProcessors(internalPostProcessors, beanFactory);
//注册实现MergedBeanDefinitionPostProcessor接口的BeanPostProcessor
registerBeanPostProcessors(beanFactory, (List)internalPostProcessors);
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
其实看注释的话,这段代码的功能基本就全部了解了。
3.5.3 扩展点
这里有一个疑问:invokeBeanFactoryPostProcessors方法中,对于BeanFactoryPostProcessor,需要从硬编码和配置两方面进行处理,但是registerBeanPostProcessors方法中处理BeanPostProcessor时却没有从硬编码和配置两个方面进行处理,为什么嘞?
答:因为对于BeanFactoryPostProcessor,不止要注册,还要调用,所以需要把所有BeanFactoryPostProcessor找出并调用;而registerBeanPostProcessors只是注册BeanPostProcessor,不需要调用,故不需要硬编码。
在3.5.2的源码中有三处类似如下代码的地方,这里又有一个疑问:假如一个处理器A实现了PriorityOrdered和MergedBeanDefinitionPostProcessor两个接口,那么在如下代码中会在两个缓存中都添加A,最终注册到beanFactory的时候,由于会注入到一个beanPostProcessors中,此时是否会出现重复的A的现象呢?
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
答:不会。spring早都想到这个问题了,哈哈哈。既然担心注册的时候出问题,那么就进入注册BeanPostProcessor的方法registerBeanPostProcessors看看。
(这里的registerBeanPostProcessors是registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, List postProcessors),不是3.5标题上的registerBeanPostProcessors(beanFactory)方法,而是其重载方法)
源码:
private static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
Iterator var2 = postProcessors.iterator();
while(var2.hasNext()) {
BeanPostProcessor postProcessor = (BeanPostProcessor)var2.next();
beanFactory.addBeanPostProcessor(postProcessor);
}
}
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
/************************* 关键点 ***************************
this.beanPostProcessors.remove(beanPostProcessor);
this.beanPostProcessors.add(beanPostProcessor);
**************************/
if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
this.hasInstantiationAwareBeanPostProcessors = true;
}
if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
this.hasDestructionAwareBeanPostProcessors = true;
}
}
这样处理的话,遇到重复的会先删再添加,避免重复。
3.6 初始化initApplicationEventMulticaster()
3.6.1 spring监听器的基本使用
自定义如下事件:
public class TestEvent extends ApplicationEvent {
public TestEvent(Object source) {
super(source);
}
}
自定义监听器:
public class TestListener implements ApplicationListener<ApplicationEvent> {
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof TestEvent){
System.out.println("bingo");
}
}
}
将TestListener 作为一个bean放入容器,并写如下测试类:
@Test
public void test2(){
AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Cap12Config.class);
TestEvent event = new TestEvent("start");
app.publishEvent(event);
}
这就完成了一个基本的事件处理。
这个过程运用到了设计模式中的观察者模式。
3.6.2 initApplicationEventMulticaster源码
spring会判断是否用户自定义了广播器,若没有,则使用默认的ApplicationEventMulticaster。
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
if (beanFactory.containsLocalBean("applicationEventMulticaster")) {
this.applicationEventMulticaster = (ApplicationEventMulticaster)beanFactory.getBean("applicationEventMulticaster", ApplicationEventMulticaster.class);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
} else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton("applicationEventMulticaster", this.applicationEventMulticaster);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Unable to locate ApplicationEventMulticaster with name 'applicationEventMulticaster': using default [" + this.applicationEventMulticaster + "]");
}
}
}
spring的广播器,其可以存放监听器并在需要的时候调用监听器。进入spring默认的广播器SimpleApplicationEventMulticaster中,可以看到有如下代码:
public void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = eventType != null ? eventType : this.resolveDefaultEventType(event);
Iterator var4 = this.getApplicationListeners(event, type).iterator();
while(var4.hasNext()) {
ApplicationListener<?> listener = (ApplicationListener)var4.next();
Executor executor = this.getTaskExecutor();
if (executor != null) {
executor.execute(() -> {
this.invokeListener(listener, event);
});
} else {
this.invokeListener(listener, event);
}
}
}
代码逻辑简单来说就是遍历监听器,然后执行监听器。
3.7 registerListeners():注册监听器
和广播器配套使用。感觉不是很重要,略。
3.8 finishBeanFactoryInitialization(beanFactory):非懒加载单例bean的创建
这个可以参考bean加载那一篇。不多赘述。这里讲些别的。
先上源码:
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
//ConversionService的设置
if (beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) {
beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class));
}
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver((strVal) -> {
return this.getEnvironment().resolvePlaceholders(strVal);
});
}
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
String[] var3 = weaverAwareNames;
int var4 = weaverAwareNames.length;
for(int var5 = 0; var5 < var4; ++var5) {
String weaverAwareName = var3[var5];
this.getBean(weaverAwareName);
}
beanFactory.setTempClassLoader((ClassLoader)null);
//冻结所有bean定义,已有的bean定义无法再做修改
beanFactory.freezeConfiguration();
//加载剩下的单实例bean
beanFactory.preInstantiateSingletons();
}
3.8.1 ConversionService的设置
使用:
//自定义转换器
public class String2DateConverter implements Converter<String, Date> {
public Date convert(String s) {
return new Date();
}
}
//在配置类中增加ConversionServiceFactoryBean类型的bean,并注入String2DateConverter
@Bean
public ConversionServiceFactoryBean conversionService(){
ConversionServiceFactoryBean conversionServiceFactoryBean = new ConversionServiceFactoryBean();
HashSet<Converter> set = new HashSet<Converter>();
Converter converter = new String2DateConverter();
set.add(converter);
conversionServiceFactoryBean.setConverters(set);
return conversionServiceFactoryBean;
}
详细的可以参考以下链接:
【小家Spring】聊聊Spring中的数据转换:Converter、ConversionService、TypeConverter、PropertyEditor
springmvc的 自定义转换器(converter)实现方法
3.8.2 冻结配置
public void freezeConfiguration() {
this.configurationFrozen = true;
this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames);
}
3.9 finishRefresh()
protected void finishRefresh() {
this.clearResourceCaches();
this.initLifecycleProcessor();
this.getLifecycleProcessor().onRefresh();
this.publishEvent((ApplicationEvent)(new ContextRefreshedEvent(this)));
LiveBeansView.registerApplicationContext(this);
}
3.9.1initLifecycleProcessor():
当ApplicationContext启动或停止时,会通过LifecycleProcessor来与所有声明的bean的周期做状态更新。而在使用LifecycleProcessor时,需要初始化。以下为源码。
protected void initLifecycleProcessor() {
ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
if (beanFactory.containsLocalBean("lifecycleProcessor")) {
this.lifecycleProcessor = (LifecycleProcessor)beanFactory.getBean("lifecycleProcessor", LifecycleProcessor.class);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
}
} else {
DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
defaultProcessor.setBeanFactory(beanFactory);
this.lifecycleProcessor = defaultProcessor;
beanFactory.registerSingleton("lifecycleProcessor", this.lifecycleProcessor);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Unable to locate LifecycleProcessor with name 'lifecycleProcessor': using default [" + this.lifecycleProcessor + "]");
}
}
}
可以看出,这里和初始化广播器时很像,如果用户自定义,则使用用户自定义的;否则用spring默认的。
3.9.2 this.publishEvent((ApplicationEvent)(new ContextRefreshedEvent(this)));
当完成ApplicationContext的初始化时,要通过spring中的事件发布机制发出ContextRefreshedEvent事件,从而使得监听器做进一步处理。
源码如下:
protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
Assert.notNull(event, "Event must not be null");
if (this.logger.isTraceEnabled()) {
this.logger.trace("Publishing event in " + this.getDisplayName() + ": " + event);
}
Object applicationEvent;
if (event instanceof ApplicationEvent) {
applicationEvent = (ApplicationEvent)event;
} else {
applicationEvent = new PayloadApplicationEvent(this, event);
if (eventType == null) {
eventType = ((PayloadApplicationEvent)applicationEvent).getResolvableType();
}
}
if (this.earlyApplicationEvents != null) {
this.earlyApplicationEvents.add(applicationEvent);
} else {
this.getApplicationEventMulticaster().multicastEvent((ApplicationEvent)applicationEvent, eventType);
}
if (this.parent != null) {
if (this.parent instanceof AbstractApplicationContext) {
((AbstractApplicationContext)this.parent).publishEvent(event, eventType);
} else {
this.parent.publishEvent(event);
}
}
}