a、Spring在扫描到对应的类以后又在核心方法中做了什么事情?
在上环节把写了相关注解的主要是@Componment、@Named、@ManagedBean的类扫描到以后封装成BeanDefinition然后放入beanDefinitionMap、beanDefinitionNames中然后开始执行核心方法的执行
1、核心方法refresh()
在核心方法中主要包含13个方法,每个方法都做了不同的事情
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
//准备预处理:记录容器的启动时间startupDate, 标记容器为激活,初始化上下文环境如文件路径信息,验证必填属性是否填写
prepareRefresh();
//告诉子类去刷新bean工厂,此方法解析配置文件并将bean信息存储到beanDefinition中,注册到BeanFactory
//(但是未被初始化,仅将信息写到了beanDefination的map中)
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//设置beanFactory的基本属性:类加载器,添加多个beanPostProcesser
prepareBeanFactory(beanFactory);
try {
//扩展机制: 允许上下文子类中对bean工厂进行后处理
postProcessBeanFactory(beanFactory);
//调用BeanFactoryPostProcessor各个实现类的方法
invokeBeanFactoryPostProcessors(beanFactory);
//注册 BeanPostProcessor 的实现类
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
//初始化ApplicationContext的MessageSource组件(资源文件),如国际化文件,消息解析,绑定等
initMessageSource();
//初始化ApplicationContext事件广播器
initApplicationEventMulticaster();
//在特定上下文子类中初始化其他特殊bean
onRefresh();
//获取所有的事件监听器,并将监听器注册到事件广播器
registerListeners();
//初始化所有不是懒加载的singleton bean
finishBeanFactoryInitialization(beanFactory);
//广播事件:ApplicationContext初始化完成
finishRefresh();
} catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
destroyBeans();
cancelRefresh(ex);
throw ex;
}
finally {
// 重置 Spring 核心中的公共自省缓存,因为我们可能不再需要单例 bean 的元数据
resetCommonCaches();
contextRefresh.end();
}
}
}
1、prepareRefresh()
该方法就是准备环境对象 Environment 对象( ApplicationContext 的一个成员变量)
Environment 其中常见的一个用途就是为后续 @Value,值注入时提供键值;
Environment 包含3个内容:
systemProperties:系统属性(主要包含jdk的路劲、java版本、vm相关信息以及其他的等等等)
systemEnvironment :系统环境(主要包含java_home、电脑账号信息等等)
自定义 PropertySource:存自定义键值,例如来自于 *.properties 文件的键值其中initPropertySources() :这个方法是为了给用户自己实现初始化逻辑,可以初始化一些属性资源。因此Spring并没有实现这个方法;validateRequiredProperties() :这个方法是对一些启动必须的属性的验证。我们可以通过实现或者继承 ApplicationContext 来重写这两个方法,从而完成一些基本属性的校验。
protected void prepareRefresh() {
//记录时间
this.startupDate = System.currentTimeMillis();
//设置当前容器未关闭
this.closed.set(false);
//设置当前容器已激活
this.active.set(true);
if (this.logger.isInfoEnabled()) {
//打印容器刷新日志
this.logger.info("Refreshing " + this);
}
//初始化一下属性(该方法默认是空的,是提供给子类来实现的,
//假设我们有些工作需要在初始化bean以前就要加载设置等,可以通过重写这个方法来完成)
this.initPropertySources();
//校验设置的属性是否合法
this.getEnvironment().validateRequiredProperties();
//初始化一个集合属性,提供用来保存后面创建的事件,如果有事件发生会放入这个集合中
this.earlyApplicationEvents = new LinkedHashSet();
}
2、ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory()
BeanFactory:ApplicationContext 的一个成员变量
这里就是直接获取beanFactory了,不会像ClassPathXmlApplicationContext --》AbstractXmlApplicationContext --》AbstractRefreshableConfigApplicationContext 一样走重新如果存在factory则销毁冲i性能创建beanFactory的流程;而是直接AnnotationConfigApplicationContext --》 GenericApplicationContext。在创建AnnotationConfigApplicationContext 的时候就创建好了GenericApplicationContext,顺带把DefaultListableBeanFactory创建好了。本质原因是因为GenericApplicationContext是一个简单的实现主要应用注解的,能够组合读取。
AbstractRefreshableApplicationContext
是一个可刷新的应用程序上下文实现,具有更多的灵活性和扩展性。读取配置可以从xml 、properties、config等,需要的是不同的BeanDefinitionReader。具备一定的扩展性,但是不能组合读取。
@Override
protected final void refreshBeanFactory() throws IllegalStateException {
if (!this.refreshed.compareAndSet(false, true)) {
throw new IllegalStateException(
"GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
}
this.beanFactory.setSerializationId(getId());
}
3、prepareBeanFactory(beanFactory)
进一步完善 BeanFactory,为它的各项成员变量赋值
1、beanExpressionResolver 用来解析 SpEL,常见实现为 StandardBeanExpressionResolver
2、propertyEditorRegistrars 会注册类型转换器,它在这里使用了 ResourceEditorRegistrar 实现类并应用 ApplicationContext 提供的 Environment 完成 ${ } 解析
3、registerResolvableDependency 来注册 beanFactory 以及 ApplicationContext,让它们也能用于依赖注入
4、beanPostProcessors 是 bean 后处理器集合,会工作在 bean 的生命周期各个阶段,此处会添加两个:
ApplicationContextAwareProcessor 用来解析 Aware 接口
ApplicationListenerDetector 用来识别容器中 ApplicationListener 类型的 bean
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
// 设置beanFactory的classloader为当前context的classloader
beanFactory.setBeanClassLoader(getClassLoader());
// 设置beanfactory的表达式语言处理器
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
// 为beanFactory增加一个默认的propertyEditor,这个主要是对bean的属性等设置管理的一个工具类。扩展bean属性。属性编辑注册,是Spring预留的一个扩展点
// 后面在进行属性填充的时候会调用这个属性编辑器进行属性的解析
//添加一个属性编辑注册员,注册员下面可以将编辑器与注册表(接口)绑定在一起,最终实现可以查到和添加解析器的功能
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
// 添加beanPostProcessor后置处理器,ApplicationContextAwareProcessor此类用来完成某些Aware对象的注入
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//忽略感知接口。XXXAware只是不能自动注入到XX对象中,Spring容器中依然有XXXAware实例
// 由于上面设置了这六个接口,因此再自动装配的时候忽略掉。
// 设置要忽略自动装配的接口,这些接口的实现是由容器通过set方法进行注入的,
// Aware接口的意义在于方便通过Spring中的Bean对象来获取其在容器中对应的相关属性值
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 interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
// 设置几个自动装配的特殊规则,当在进行ioc初始化的如果有多个实现,那么就使用指定的对象进行注入
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// Register early post-processor for detecting inner beans as ApplicationListeners.
// 注册BPP
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
// 增加对AspectJ的支持,在java中织入分为三种方式,分为编译器织入,类加载器织入,运行期织入,编译器织入是指在java编译器,采用特殊的编译器,将切面织入到java类中,
// 而类加载期织入则指通过特殊的类加载器,在类字节码加载到JVM时,织入切面,运行期织入则是采用cglib和jdk进行切面的织入
// aspectj提供了两种织入方式,第一种是通过特殊编译器,在编译器,将aspectj语言编写的切面类织入到java类中,第二种是类加载期织入,就是下面的load time weaving,此处后续讲
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// Register default environment beans.
// 注册默认的系统环境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());
}
}
3.1、属性编辑器扩展
简单概括:beanFactory.addPropertyEditorRegistrar :给 BeanFactory 设置一个默认的PropertyEditor,主要对Bean的属性值编辑管理的工具类,是Spring预留的一个扩展点,在xml中给一个实体bean注入一个日期类型的属性?或者再使用@Value注解的时候 类属性定义的是Date,配置文件中配置的是String,那Spring注入时是无法将String类型解析成Date类型的。要解决该问题就得自定义一个属性编辑器来转换日期类型。
调用时机:自定义的属性编辑器是在实例化第一个容器读取到的对象的时候就会把自定义的编辑器也加到容器中然后在初始化bean对象中的populateBean()填充属性环节进行设置的转换的,可以通过debug看
(1)自定义日期属性编辑器
public class DatePropertyEditor extends PropertyEditorSupport {
private DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT, Locale.CHINA);
@Override
public void setAsText(String text) throws IllegalArgumentException {
if (!StringUtils.hasText(text)) {
return;
}
try {
//通过方法调用链路可以看出该方法是在Bean生命周期的Bean对象属性填充 时调用的
setValue(this.dateFormat.parse(text));
} catch (ParseException ex) {
throw new IllegalArgumentException("Could not parse date: " + ex.getMessage(), ex);
}
}
}
(2)日期属性编辑器注册到Spring容器中
public class DatePropertyEditorRegistrar implements PropertyEditorRegistrar {
/**
* 通过方法调用链路可以看出registerCustomEditors方法是在Bean生命周期的Bean对象实例化之后、对象属性填充之前 调用的
*/
@Override
public void registerCustomEditors(PropertyEditorRegistry registry) {
registry.registerCustomEditor(Date.class, new DatePropertyEditor());
}
}
(3)xml文件配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="person1" class="com.my.Person">
<property name="age" value="18"></property>
<property name="name" value="zs"></property>
<property name="birth" value="2023-09-07"></property>
</bean>
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="propertyEditorRegistrars">
<list>
<bean class="com.my.editor.DatePropertyEditorRegistrar"></bean>
</list>
</property>
</bean>
</beans>
(4)运行结果
ApplicationContext ac2 = new ClassPathXmlApplicationContext("ApplicationContext.xml");
Person person = (Person)ac2.getBean("person1");
System.out.println(person.getBirth());
输出结果 Thu Sep 07 00:00:00 CST 2023
3.2、ApplicationContextAwareProcessor处理器
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this))
为 BeanFactoty 添加 BeanPostProcessor 处理器,只不过这个处理器是 ApplicationContextAwareProcessor,它到底干了什么事?在Bean的生命周期流程中populateBean完成bean属性填充之后,会调用 initializeBean方法,该方法依次调用Aware接口、BeanPostProcessor前置处理器、init-method、调用BeanPostProcessor后置处理器。
但是我们发现通过invokeAwareMethods调用 Aware接口时只处理了BeanNameAware、 BeanClassLoaderAware、BeanFactoryAware 三个接口,那么其他的Aware接口是在哪里处理的呢???
ApplicationContextAwareProcessor 就是处理其他Aware接口的。因为它是BeanPostProcessor,所以在postProcessBeforeInitialization中做了 Aware 接口处理逻辑
class ApplicationContextAwareProcessor implements BeanPostProcessor {
private final ConfigurableApplicationContext applicationContext;
private final StringValueResolver embeddedValueResolver;
public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {
this.applicationContext = applicationContext;
this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory());
}
@Override
@Nullable
public Object postProcessBeforeInitialization(final 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((PrivilegedAction<Object>) () -> {
invokeAwareInterfaces(bean);
return null;
}, acc);
}
else {
invokeAwareInterfaces(bean);
}
return bean;
}
// 处理其他 Aware 接口
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);
}
}
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
return bean;
}
}
所以 EnvironmentAware EmbeddedValueResolverAware ResourceLoaderAware ApplicationEventPublisherAware MessageSourceAware ApplicationContextAware 这些接口的调用时机是在BeanPostProcessor前置处理器中处理的。
4、postProcessBeanFactory(beanFactory)
这一步是空实现,留给子类扩展。 一般 Web 环境的 ApplicationContext 都要利用它注册新的 Scope,完善 Web 下的 BeanFactory;这里体现的是模板方法设计模式
5、invokeBeanFactoryPostProcessors(beanFactory) (重点方法单独讲)
-
这一步会调用 beanFactory 后处理器,beanFactory 后处理器,充当 beanFactory 的扩展点,可以用来补充或修改 BeanDefinition,springboot得自动装配得原理也在这一步实现得。
-
常见的 beanFactory 后处理器有
-
ConfigurationClassPostProcessor – 解析 @Configuration、@Bean、@Import、@PropertySource 等
-
PropertySourcesPlaceHolderConfigurer – 替换 BeanDefinition 中的 ${ }
-
MapperScannerConfigurer – 补充 Mapper 接口对应的 BeanDefinition
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
//执行beanFactory后置处理器中的方法,该方法中获取所有BeanFactoryPostProcessor,遍历判断
//对不同的BeanFactoryPostProcessor进行排序,因为先后执行的顺序不同,
//PriorityOrdered>BeanDefinitionRegistryPostProcessor>BeanFactoryPostProcessor
//然后执行后置处理器中定义的初始化 beanFactory 后要执行的方法
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors());
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean("loadTimeWeaver")) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
6、registerBeanPostProcessors(beanFactory)(单独介绍)
-
这一步是继续从 beanFactory 中找出 bean 后处理器,添加至 beanPostProcessors 集合中
-
bean 后处理器,充当 bean 的扩展点,可以工作在 bean 的实例化、依赖注入、初始化阶段,常见的有:
-
AutowiredAnnotationBeanPostProcessor 功能有:解析 @Autowired,@Value 注解
-
CommonAnnotationBeanPostProcessor 功能有:解析 @Resource,@PostConstruct,@PreDestroy
-
AnnotationAwareAspectJAutoProxyCreator 功能有:为符合切点的目标 bean 自动创建代理
注意不同的 BeanPostProcessors,该接口下的子接口: 不同接口的执行时机不同
DestructionAwareBeanPostProcessor
InstantiationAwareBeanProcessor
SmartInstantiationAwareBeanPostProcessor
MergedBeanDefinitionPostProcessor
public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
//根据类型获取 beanFactory 中所有的 BeanPostProcessor 名字
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
//添加了一个后置处理器,通过添加的这个后置处理器检查 前获取的这些后置处理器 BeanPostProcessorChecker 是一个内部类,继承了BeanPostProcessor接口
beanFactory.addBeanPostProcessor(new PostProcessorRegistrationDelegate.BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
//创建两个集合用来存放不同的BeanPostProcessor,通过这两个集合对不同的BeanPostProcessor 进行排序
List priorityOrderedPostProcessors = new ArrayList();
List internalPostProcessors = new ArrayList();
List orderedPostProcessorNames = new ArrayList();
List nonOrderedPostProcessorNames = new ArrayList();
String[] var8 = postProcessorNames;
int var9 = postProcessorNames.length;
String ppName;
BeanPostProcessor pp;
//遍历获取 BeanPostProcessor, 判断不同的 BeanPostProcessor 放入不同的集合中
//实现了 PriorityOrdered 的放入priorityOrderedPostProcessors集合中
//实现了PriorityOrdered 并且是MergedBeanDefinitionPostProcessor类型的放入internalPostProcessors
//实现了 Ordered 的放入 orderedPostProcessorNames 集合中
//否则放入 nonOrderedPostProcessorNames 集合中
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);
}
}
//首先对 priorityOrderedPostProcessors 中的进行排序
sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
//注册,也就是创建BeanPostProcessor设置到beanFactory中
registerBeanPostProcessors(beanFactory, (List)priorityOrderedPostProcessors);
List orderedPostProcessors = new ArrayList();
Iterator var14 = orderedPostProcessorNames.iterator();
//遍历orderedPostProcessorNames集合中的BeanPostProcessor 如果有
//MergedBeanDefinitionPostProcessor类型的,将这个类型的后置处理器放入internalPostProcessors集合
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);
}
}
//对orderedPostProcessors集合中的后置处理器排序
sortPostProcessors(beanFactory, orderedPostProcessors);
//注册
registerBeanPostProcessors(beanFactory, (List)orderedPostProcessors);
List nonOrderedPostProcessors = new ArrayList();
Iterator var17 = nonOrderedPostProcessorNames.iterator();
//继续排序,分类
while(var17.hasNext()) {
ppName = (String)var17.next();
pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
//注册nonOrderedPostProcessors集合中的后置处理器
registerBeanPostProcessors(beanFactory, (List)nonOrderedPostProcessors);
//对internalPostProcessors集合中的后置处理器进行排序
sortPostProcessors(beanFactory, internalPostProcessors);
//注册internalPostProcessors集合中的后置处理器
registerBeanPostProcessors(beanFactory, (List)internalPostProcessors);
//又添加了一个后置处理器ApplicationListenerDetector,
//该后置处理器用来判断是否是某个监听器,如果是添加到容器中
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
7、initMessageSource()
这一步是为 ApplicationContext 添加 messageSource 成员,实现国际化功能
去 beanFactory 内找名为 messageSource 的 bean,如果没有,则提供空的 MessageSource 实现
protected void initMessageSource() {
//获取beanFactory
ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
//判断beanFactory中是否有一个id为"messageSource" 的 bean
if (beanFactory.containsLocalBean("messageSource")) {
//如果有通过id获取这个bean,赋值给 messageSource 属性
this.messageSource = (MessageSource)beanFactory.getBean("messageSource", MessageSource.class);
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource)this.messageSource;
if (hms.getParentMessageSource() == null) {
hms.setParentMessageSource(this.getInternalParentMessageSource());
}
}
if (this.logger.isDebugEnabled()) {
this.logger.debug("Using MessageSource [" + this.messageSource + "]");
}
} else {
//如果没有创建一个MessageSource组件
DelegatingMessageSource dms = new DelegatingMessageSource();
//将这个组件注册到容器中(以后获取国际化配置文件的相关信息,可以通过@Autowired在Spring
//容器中直接获取装配到自己的类的属性上,然后调用MessageSource的方法)
dms.setParentMessageSource(this.getInternalParentMessageSource());
this.messageSource = dms;
beanFactory.registerSingleton("messageSource", this.messageSource);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Unable to locate MessageSource with name 'messageSource': using default [" + this.messageSource + "]");
}
}
}
8、initApplicationEventMulticaster()
这一步为 ApplicationContext 添加事件广播器成员,即 applicationContextEventMulticaster它的作用是发布事件给监听器去 beanFactory 找名为 applicationEventMulticaster 的 bean 作为事件广播器,若没有,会创建默认的事件广播器之后就可以调用 ApplicationContext.publishEvent(事件对象) 来发布事件
protected void initApplicationEventMulticaster() {
//获取beanFactory
ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
//1.获取beanFactory中id为"applicationEventMulticaster"的事件派发器
if (beanFactory.containsLocalBean("applicationEventMulticaster")) {
this.applicationEventMulticaster = (ApplicationEventMulticaster)beanFactory.getBean("applicationEventMulticaster", ApplicationEventMulticaster.class);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
} else {
//如果没有创建一个 SimpleApplicationEventMulticaster 事件派发器,
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
//注册到 Spring 容器中
beanFactory.registerSingleton("applicationEventMulticaster", this.applicationEventMulticaster);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Unable to locate ApplicationEventMulticaster with name 'applicationEventMulticaster': using default [" + this.applicationEventMulticaster + "]");
}
}
}
9、onRefresh()
- 这一步是空实现,留给子类扩展 SpringBoot 中的子类在这里准备了 WebServer,即内嵌 web 容器。 体现的是模板方法设计模式
10、registerListeners()
- 这一步会从多种途径找到事件监听器,并添加至 applicationEventMulticaster
事件监听器顾名思义,用来接收事件广播器发布的事件主要有
事先编程添加的来自容器中的 bean
来自于 @EventListener 的解析
实现 ApplicationListener 接口,重写其中 onApplicationEvent(Event e) 方法
protected void registerListeners() {
Iterator var1 = this.getApplicationListeners().iterator();
while(var1.hasNext()) {
ApplicationListener listener = (ApplicationListener)var1.next();
this.getApplicationEventMulticaster().addApplicationListener(listener);
}
//在容器中拿到所有的监听器的名字
String[] listenerBeanNames = this.getBeanNamesForType(ApplicationListener.class, true, false);
String[] var7 = listenerBeanNames;
int var3 = listenerBeanNames.length;
//遍历,将每个监听器添加到事件派发器中
for(int var4 = 0; var4 < var3; ++var4) {
String listenerBeanName = var7[var4];
this.getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
//获取早期设置的事件(派发之前的事件)
Set earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
//如果有
if (earlyEventsToProcess != null) {
Iterator var9 = earlyEventsToProcess.iterator();
while(var9.hasNext()) {
ApplicationEvent earlyEvent = (ApplicationEvent)var9.next();
//将早期的事件派发出去
this.getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
11、finishBeanFactoryInitialization(beanFactory)
这一步会初始化所有非延迟单例 bean,缓存所有单例对象
conversionService 也是一套转换机制,作为对 PropertyEditor 的补充
embeddedValueResolvers 即内嵌值解析器,用来解析 @Value 中的 ${ },借用的是 Environment 的功能
这一步是核心中得核心
12、finishRefresh()
这一步会为 ApplicationContext 添加 lifecycleProcessor 成员,用来控制容器内需要生命周期管理的 bean,如果容器中有名称为 lifecycleProcessor 的 bean 就用它,否则创建默认的生命周期管理器,准备好生命周期管理器,就可以实现
调用 context 的 start,即可触发所有实现 LifeCycle 接口 bean 的 start;
调用 context 的 stop,即可触发所有实现 LifeCycle 接口 bean 的 stop;
发布 ContextRefreshed 事件,整个 refresh 执行完成
protected void finishRefresh() {
//初始化跟生命周期有关的后置处理器,在容器中获取LifecycleProcessor
//类型的后置处理器接口,在容器刷新完成以及关闭时执行的方法,此处是注册
//如果没有会注册一个默认的生命周期组件
this.initLifecycleProcessor();
//拿到生命周期处理器,回调onRefresh()容器刷新完成方法,
this.getLifecycleProcessor().onRefresh();
//发布容器刷新完成事件
this.publishEvent((ApplicationEvent)(new ContextRefreshedEvent(this)));
LiveBeansView.registerApplicationContext(this);
}
13、resetCommonCaches()
清空产生的缓存数据