前言
Spring
框架中最重要的肯定是IOC容器,那么其如何进行初始化,就是通过refresh()
这个方法,无论是单独使用Spring框架,还是SpringBoot
,最终都会通过执行到这个方法,那么下面会介绍一下这个方法
一、IOC容器初始化过程
对于单独测试Spirng框架的场景,有两个常见的高级容器 AnnotationConfigApplicationContext
和 ClassPathXmlApplicationContext
,在这两个类的构造方法,都会使用到refresh()
来刷新容器
AnnotationConfigApplicationContext
AnnotationConfigApplicationContext
会通过扫描配置类来创建IOC容器
@Test
public void m1() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AspectConfig.class);
MathCalculator mathCalculator = context.getBean(MathCalculator.class);
int ans = mathCalculator.div(10, 5);
System.out.println("结果:" + ans);
}
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
// 调用无参构造方法
this();
// 注册新的组件
register(componentClasses);
// 刷新容器
refresh();
}
构造方法
public AnnotationConfigApplicationContext() {
StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
// 创建注解Reader
this.reader = new AnnotatedBeanDefinitionReader(this);
createAnnotatedBeanDefReader.end();
// 创建类扫描
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
创建的AnnotatedBeanDefinitionReader
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
// 这里最后一行很关键,注册了一些核心的BeanPostProcessor
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
下面的方法就是容器启动时初始化,注册一些基础使用的类,其中有一个需要着重看一眼的就是负责处理@Configuration
的后置处理器ConfigurationClassPostProcessor
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
registerAnnotationConfigProcessors(registry, null);
}
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
// 这里是最重要的,就是注册用来处理@Configuration注解的后置处理器
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 省略了一些代码
return beanDefs;
}
ClassPathXmlApplicationContext
加载bean的xml文件,底层也是通过refresh()
方式
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
二、refresh()
方法简介
refresh()
为ConfigurableApplicationContext
中的接口,子类AbstractApplicationContext
重写了该方法,负责初始化IOC容器
该方法中总共包含12个方法,大体的工作内容介绍:
- 刷新前的准备工作
- 获取Bean工厂
- 工厂前期的准备
- 子类重写方法,可以对Bean工厂进行扩展
- 执行BeanFactory的后置处理器
- 注册Bean的后置处理器
- 初始化消息源,负责国际化
- 初始化上下文事件
- 子类重写方法,初始化其它特殊bean
- 注册监听器
- 工厂基本创建完毕,剩余的收尾工作
- 刷新完成,剩余的收尾工作
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// Prepare this context for refreshing.
// <1> 准备预处理:记录容器的启动时间startupDate, 标记容器为激活,初始化上下文环境如文件路径信息,验证必填属性是否填写
prepareRefresh();
// <2> 告诉子类去刷新bean工厂,此方法解析配置文件并将bean信息存储到beanDefinition中,注册到BeanFactory
//(但是未被初始化,仅将信息写到了beanDefination的map中)**重点方法,下面的操作都基于这个beanFactory进行的
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
// <3> 设置beanFactory的基本属性:类加载器,添加多个beanPostProcesser
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
// <4> 扩展机制: 允许上下文子类中对bean工厂进行后处理
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
/**************************以上是BeanFactory的创建及预准备工作 ****************/
// Invoke factory processors registered as beans in the context.
// <5> 调用BeanFactoryPostProcessor各个实现类的方法
invokeBeanFactoryPostProcessors(beanFactory);
// <6> 注册 BeanPostProcessor 的实现类
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// <7> 初始化ApplicationContext的MessageSource组件(资源文件),如国际化文件,消息解析,绑定等
initMessageSource();
// <8> 初始化ApplicationContext事件广播器
initApplicationEventMulticaster();
// <9> 在特定上下文子类中初始化其他特殊bean
onRefresh();
// <10> 获取所有的事件监听器,并将监听器注册到事件广播器
registerListeners();
// <11> 初始化所有不是懒加载的singleton bean
finishBeanFactoryInitialization(beanFactory);
// <12> 广播事件:ApplicationContext初始化完成
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// 重置 Spring 核心中的公共自省缓存,因为我们可能不再需要单例 bean 的元数据......
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
contextRefresh.end();
}
}
}
<1> prepareRefresh() 刷新准备
1、prepareRefresh()刷新前的预处理;
1)、initPropertySources()初始化一些属性设置;子类自定义个性化的属性设置方法;
2)、getEnvironment().validateRequiredProperties();检验属性的合法等
3)、earlyApplicationEvents= new LinkedHashSet<>();保存容器中的一些早期的事件;
/**
* Prepare this context for refreshing, setting its startup date and 容器刷新的准备工作,设置启动时间
* active flag as well as performing any initialization of property sources. 以及初始化属性源
*/
protected void prepareRefresh() {
// Switch to active.
this.startupDate = System.currentTimeMillis(); // 获取当前时间
// 设置关闭状态false 启动状态true
this.closed.set(false);
this.active.set(true);
// 输出日志
if (logger.isDebugEnabled()) {
if (logger.isTraceEnabled()) {
logger.trace("Refreshing " + this);
}
else {
logger.debug("Refreshing " + getDisplayName());
}
}
// Initialize any placeholder property sources in the context environment.
// 初始化一些属性在容器环境中 留给子类重写
initPropertySources();
// Validate that all properties marked as required are resolvable:
// see ConfigurablePropertyResolver#setRequiredProperties
// 验证属性的是否合法
getEnvironment().validateRequiredProperties();
// Store pre-refresh ApplicationListeners...
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
// Reset local application listeners to pre-refresh state.
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
// Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
// 通过集合保存早期的容器事件
// 等派发起好了以后,在派发出去
this.earlyApplicationEvents = new LinkedHashSet<>();
}
a> initPropertySources()
是个空方法,留给子类重写自定义
/**
* <p>Replace any stub property sources with actual instances.
* @see org.springframework.core.env.PropertySource.StubPropertySource
* @see org.springframework.web.context.support.WebApplicationContextUtils#initServletPropertySources
*/
protected void initPropertySources() {
// For subclasses: do nothing by default.
}
b> validateRequiredProperties()
验证请求属性,方法很简单,循环遍历,判断是否为Null,存在则直接抛出异常MissingRequiredPropertiesException
,该异常为自定义异常类
public void validateRequiredProperties() {
// 创建异常信息
MissingRequiredPropertiesException ex = new MissingRequiredPropertiesException();
Iterator var2 = this.requiredProperties.iterator();
// 遍历 找到空的key
while(var2.hasNext()) {
String key = (String)var2.next();
if (this.getProperty(key) == null) {
ex.addMissingRequiredProperty(key);
}
}
// 存在空的直接抛出异常
if (!ex.getMissingRequiredProperties().isEmpty()) {
throw ex;
}
}
<2> obtainFreshBeanFactory() 获取bean工厂
该方法很简单,获取到对应的bean工厂,类型为DefaultListableBeanFactory
,也是Spring中功能最全的IOC容器
/**
* Tell the subclass to refresh the internal bean factory.
* @return the fresh BeanFactory instance 返回容器示例
* @see #refreshBeanFactory()
* @see #getBeanFactory()
*/
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
// 刷新容器
refreshBeanFactory();
// 通过getter方法获取到Bean工厂返回,其实就是默认的DefaultListableBeanFactory
return getBeanFactory();
}
a> refreshBeanFactory()
在GenericApplicationContext
类初始化的时候,就创建了一个默认的BeanFactory
,然后这里会设置Id
- 创建的beanFactory是
DefaultListableBeanFactory
类型 - 该beanFactory在类初始化的时候就创建了
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {
// 构造方法
public GenericApplicationContext() {
// 这里也代表了DefaultListableBeanFactory是Spring中最核心的类
this.beanFactory = new DefaultListableBeanFactory();
}
/**
* Do nothing: We hold a single internal BeanFactory and rely on callers
* to register beans through our public methods (or the BeanFactory's).
* @see #registerBeanDefinition
*/
@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");
}
// 这个id就是 org.springframework.context.annotation.AnnotationConfigApplicationContext@5b0abc94
this.beanFactory.setSerializationId(getId());
}
// ...
}
<3> prepareBeanFactory() 准备工厂
3、prepareBeanFactory(beanFactory);BeanFactory的预准备工作(BeanFactory进行一些设置);
1)、设置BeanFactory的类加载器、支持表达式解析器...
2)、添加部分BeanPostProcessor【ApplicationContextAwareProcessor】
3)、设置忽略的自动装配的接口EnvironmentAware、EmbeddedValueResolverAware、xxx;
4)、注册可以解析的自动装配;我们能直接在任何组件中自动注入:
BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext
5)、添加BeanPostProcessor【ApplicationListenerDetector】
6)、添加编译时的AspectJ
7)、给BeanFactory中注册一些能用的组件;
environment【ConfigurableEnvironment】、
systemProperties【Map<String, Object>】、
systemEnvironment【Map<String, Object>】
/**
* Configure the factory's standard context characteristics, 配置工厂启动时上下文特征
* such as the context's ClassLoader and post-processors. 例如容器的类加载器和后置处理器
* @param beanFactory the BeanFactory to configure
*/
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
// 1.设置Bean的类加载器
beanFactory.setBeanClassLoader(getClassLoader());
if (!shouldIgnoreSpel) {
// 设置支持相关表达式语言的解析器
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
}
// 添加属性的编辑注册器
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
// 2.添加部分后置处理器【ApplicationContextAwareProcessor】
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 3.设置忽略自动装配的接口
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.ignoreDependencyInterface(ApplicationStartupAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
// 4.注册可以解析的自动装配
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.
// 5.添加BeanPostProcessor【ApplicationListenerDetector】事件监听
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
if (!NativeDetector.inNativeImage() && 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.
// 给BeanFactory中注册一些能用的组件
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());
}
if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
}
}
<4> postProcessBeanFactory() 子类重写扩展
提供的扩展机制,子类通过重写这个方法来在BeanFactory创建并预准备完成以后做进一步的设置
/**
* Modify the application context's internal bean factory after its standard
* initialization. All bean definitions will have been loaded, but no beans
* will have been instantiated yet. This allows for registering special
* BeanPostProcessors etc in certain ApplicationContext implementations.
* @param beanFactory the bean factory used by the application context
*/
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}
<5> invokeBeanFactoryPostProcessors()
a> 方法入口
这个方法会继续调用一个包装类中的方法,负责执行后置处理器,其中的参数getBeanFactoryPostProcessors()
会获取后置处理器,这里获取的后置处理器是框架初始化需要的,会被优先执行
但需要注意的是,并不是Spring框架需要的,在实际测试过程中,如果使用SpringBoot
,可以成功获取到,如果单独启动Spring,则啥也没有
/**
* Instantiate and invoke all registered BeanFactoryPostProcessor beans,
* respecting explicit order if given.
* <p>Must be called before singleton instantiation.
*/
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// 执行后置处理器
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
上面两张图也说明了问题,如果想在Spring框架基础上封装其它框架,例如经典的SpringBoot
,Spring会先执行SpringBoot
初始化需要的后置处理器,保证核心框架先顺利启动,然后再执行其它依赖和手写的后置处理器
当然侧面证明了Spring
提供的良好的扩展性能,再启动Spring的时候,优先执行二次封装的代码,最后在是其它依赖和自己写的代码
b> 接口介绍
下面方法会用到这2个接口,这里先介绍一下
BeanFactoryPostProcessor
BeanFactoryPostProcessor
的执行时机为容器初始化后,实例化Bean前,Spring允许在这个时候可以对Bean工厂进行修改,一种良好的扩展性能
public interface BeanFactoryPostProcessor {
// 通过参数ConfigurableListableBeanFactory可以获取到定义信息
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
使用示例
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("调用MyBeanFactoryPostProcessor的postProcessBeanFactory");
BeanDefinition bd = beanFactory.getBeanDefinition("mathCalculator");
System.out.println("属性值------>" + bd.getPropertyValues().toString());
MutablePropertyValues pv = bd.getPropertyValues();
if (pv.contains("remark")) {
pv.addPropertyValue("remark", "把备注信息修改一下");
}
bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
}
}
BeanDefinitionRegistryPostProcessor
- 通过下面的代码,看到它继承了
BeanFactoryPostProcessor
- 它会在所有的bean定义信息还未被加载,将要被加载的时候执行,可以对
BeanDefiniton
进行增删改查
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
/**
* Modify the application context's internal bean definition registry after its
* standard initialization. All regular bean definitions will have been loaded,
* but no beans will have been instantiated yet. This allows for adding further
* bean definitions before the next post-processing phase kicks in.
* @param registry the bean definition registry used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}
c> 方法分析
- 首先参数传递过来的后置处理器,该参数上面已经介绍了,这些是框架启动需要的,例如
SpringBoot
,如果是单独的Spring
启动则为空集合 - 判断是否实现了
BeanDefinitionRegistry
该接口,只有IOC容器实现了该接口,才代表允许其它代码操作BeanDefinition
,看成一个开关入口 - 执行第1步:首先执行
SpringBoot
框架需要的BeanDefinitionRegistryPostProcessor
,需要先把框架处理完毕 - 执行第2步:执行其它依赖和开发人员写的
BeanDefinitionRegistryPostProcessor
- 优先执行实现了
PriorityOrdered
接口的 - 次之执行实现了
Ordered
接口的 - 执行剩余的后置处理器
- 接下来会先执行一批
BeanFactoryPostProcessor
,上面也介绍了这2个接口是继承关系,所以重写子类方法必须也带上父类方法,上面执行的BeanDefinitionRegistryPostProcessor
后置处理器,肯定也有BeanFactoryPostProcessor
的方法,这里需要执行,这里启动就是2部分
- 先执行上面这些实现了
BeanDefinitionRegistryPostProcessor
接口,里面肯定重写了父类BeanFactoryPostProcessor
,需要先执行 - 参数传递过来的
BeanFactoryPostProcessor
,这些也需要先执行
- 到此上面已经把
BeanDefinitionRegistryPostProcessor
处理完毕,接下来就是BeanFactoryPostProcessor
,这里会和上面一样,先处理PriorityOrdered
,次之Ordered
,最后剩余的 - 总结:代码非常长,理解了很简答,总体思想就是先执行框架启动需要的,然后在执行自己写的,先执行
BeanDefinitionRegistryPostProcessor
,后BeanFactoryPostProcessor
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
// 执行BeanDefinitionRegistryPostProcessors的实现类【首先调用】
Set<String> processedBeans = new HashSet<>();
// 实现该接口才允许操作BeanDefinition,当然DefaultListableBeanFactory肯定实现了
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// <1> 处理参数传递过来的后置处理器,这些是Spring启动需要的
// 按照实现接口分类存进去, 并且优先执行实现了BeanDefinitionRegistryPostProcessor的后置方法,系统类的先执行
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// Separate between BeanDefinitionRegistryPostProcessors that implement
// PriorityOrdered, Ordered, and the rest.
// 定义一个变量,用于后续分批执行代码
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
// 第一步 执行实现了 PriorityOrdered 优先级排序接口的BeanDefinitionRegistryPostProcessors子类
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
// 第二步 执行实现了Ordered顺序接口的BeanDefinitionRegistryPostProcessors
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
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);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
// 最后 执行剩余的BeanDefinitionRegistryPostProcessors
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
}
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
// 调用到目前为止处理的所有处理器的 postProcessBeanFactory() 回调
// 这里会有一个疑问: postProcessBeanFactory()不是下面很多行代码负责执行吗?咋这里就执行了
// 首先 registryProcessors是上面实现了子类接口,那么父类肯定也给重写,那么这里先调用
// 其次 regularPostProcessors到目前位置有数据,肯定是框架启动需要的后置处理器,也要先执行
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// Invoke factory processors registered with the context instance.
// 否则执行框架启动需要的后置处理器
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// 获取所有的 BeanFactoryPostProcessor 后置处理器
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
// 第一步 执行实现 PriorityOrdered 接口的 BeanFactoryPostProcessors
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
// 第二步 执行实现 Ordered 接口的 BeanFactoryPostProcessors
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
// 第三步 执行剩余的
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
beanFactory.clearMetadataCache();
}
d> 重要Debug
如下截图所示,Spring
框架负责解析@Configuration
配置类的是后置处理器ConfigurationClassPostProcessor
,它会负责扫描各种类,把bean包装成BeanDefinition
存入IOC容器,具体后续会介绍ConfigurationClassPostProcessor
<6> registerBeanPostProcessors()
顾名思义,注册Bean后置处理器,它负责拦截Bean的创建,这样我们就可以通过该拦截对Bean添加自定义逻辑,例如Aop功能,就是通过注解添加了一个后置处理器,然后在创建Bean的时候,对其进行代理,达到增强的目的
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
- 获取所有的
BeanPostProcessor
后置处理器 - 先注册
PriorityOrdered
优先级接口的BeanPostProcessor
- 再注册
Ordered
接口的 - 最后注册没有实现任何优先级接口的
- 最终注册
MergedBeanDefinitionPostProcessor
- 注册一个
ApplicationListenerDetector
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 1.获取所有实现 BeanPostProcessor 接口的后置处理器
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// 2.记录数量 = 框架中已经存在的 + 稍后会注入的数量 + 下一行代码注入的1个后置处理器
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
// 新注册的处理器 BeanPostProcessorChecker 主要用于记录信息
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
// 3.分类存储
// 实现PriorityOrdered接口的
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
// 实现Ordered接口的name集合
List<String> orderedPostProcessorNames = new ArrayList<>();
// 定义普通的name集合
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = 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);
}
}
// 4.先注册实现 PriorityOrdered 接口的
// First, register the BeanPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// 5.次之注册实现 Ordered 接口的
// Next, register the BeanPostProcessors that implement Ordered.
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// 5.最后注册普通的后置处理器
// Now, register all regular BeanPostProcessors.
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// 6.注册实现了 MergedBeanDefinitionPostProcessor 接口的
// Finally, re-register all internal BeanPostProcessors.
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
// 7.重新注册用于将内部 bean 检测为 ApplicationListeners 的后处理器,将其移动到处理器链的末尾(用于获取代理等)
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
<7> initMessageSource() 国际化
MessageSource
是负责国际化功能的,下面的代码大体很简单,如果已经存在国际化组件,就一顿操作处理,没有就注册个新的
那么想一下,之前怎么可能会有该bean?那肯定是开发人员自定义的国际化组件,如果存在则在第<5>步的时候已经解析完毕,执行到该方法,肯定就可以获取到
那么在把下面这个方法概述一下:如果开发人员自定义了国际化组件,那就用自己写的,按照固定的格式处理一下,否则就用默认的国际化组件
这同样体现了Spring框架良好的扩展机制,后续会编写单独的文章介绍MessageSource
protected void initMessageSource() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 如果存在该bean,则代表开发人员自定义了国家化组件
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
// Make MessageSource aware of parent MessageSource.
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
// Only set parent context as parent MessageSource if no parent MessageSource
// registered already.
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
if (logger.isTraceEnabled()) {
logger.trace("Using MessageSource [" + this.messageSource + "]");
}
}
else { // 否则使用默认的国际化组件
// Use empty MessageSource to be able to accept getMessage calls.
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
this.messageSource = dms;
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
if (logger.isTraceEnabled()) {
logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
}
}
}
<8> initApplicationEventMulticaster()
下面这个方法大体逻辑和第<7>步一致,如果存在该bean,则代表开发人员自定义了该功能,则处理一下,否则注册一个默认的
ApplicationEventMulticaster
是Spring中事件广播器接口,负责事件的广播发布。
通过名字可以看出它就是一个广播站,可以把监听器注册到我这里来,有事件通过我进行发布。也可以理解为MQ种的发布-订阅
模式,监听器在这里进行订阅,有消息通过我进行发布
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isTraceEnabled()) {
logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
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() + "]");
}
}
}
ApplicationEventMulticaster
上面看懂了该组件的功能,这里看接口就好理解了,负责注册监听器的,负责发布事件的
public interface ApplicationEventMulticaster {
// 注册监听器
void addApplicationListener(ApplicationListener<?> listener);
void addApplicationListenerBean(String listenerBeanName);
// 移除监听器
void removeApplicationListener(ApplicationListener<?> listener);
void removeApplicationListenerBean(String listenerBeanName);
void removeAllListeners();
// 发布事件
void multicastEvent(ApplicationEvent event);
void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType);
}
<9> onRefresh() 子类重写扩展
在特定上下文子类中初始化其他特殊bean
protected void onRefresh() throws BeansException {
// For subclasses: do nothing by default.
}
<10> registerListeners()
在上面第<8>步,注册了一个事件广播器
,该方法负责把监听器注册到里面
protected void registerListeners() {
// 1.向事件分发器注册监听器,这些是通过配置文件读取的
// Register statically specified listeners first.
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// 2.向事件分发器注册外部加入的监听器,但不实例化
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// 3.发布早期的事件
// Publish early application events now that we finally have a multicaster...
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
<11> finishBeanFactoryInitialization()
通过名字可以看出是完成BeanFactory
的初始化,一个收尾方法,相当于一个bean工厂大部分已经完成了,还剩余零零散散的辅助bean需要依次注入
在这个方法中需要关注的是最后1行,这里会实例化未设置懒加载的单例bean
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 1.为此上下文初始化转换服务
// Initialize conversion service for this context.
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
// 2.如果之前没有注册任何 bean 后处理器(例如 PropertyPlaceholderConfigurer bean),则注册一个默认的嵌入值解析器:此时,主要用于注释属性值的解析
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
// 3.通过 getBean() 尽早的注册LoadTimeWeaverAware
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
// 4.停止使用临时类加载器进行类型匹配
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
// 5.允许缓存所有 bean 定义元数据,而不是期望进一步的更改
beanFactory.freezeConfiguration();
// 6.Instantiate all remaining (non-lazy-init) singletons.
// 初始化未懒加载的单例bean
beanFactory.preInstantiateSingletons();
}
a> preInstantiateSingletons
子类DefaultListableBeanFactory
重写了该方法
功能:循环所有的Bean名称,遍历判断,然后实例化,最后调用回调
// DefaultListableBeanFactory
@Override
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
// 1.获取全部的BeanName
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
// 2.实例化所有非懒加载的单实例Bean
for (String beanName : beanNames)
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 非抽象 && 单实例 && 非懒加载
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 类型判断是否为FactoryBean, FactoryBean在后续章节也有讲解
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(
(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
// 普通的Bean在这里直接获取
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
// 触发所有适用 bean 的初始化后回调
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
<12> finishRefresh()
上面已经把BeanFactory
初始化完毕,那么这个IOC容器就接近尾声了,接下来就是一些后续工作
protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
// 清除上下文级资源缓存
clearResourceCaches();
// Initialize lifecycle processor for this context.
// 为此上下文初始化生命周期处理器
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
getLifecycleProcessor().onRefresh();
// Publish the final event.
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}
ingleton) {
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
## <12> finishRefresh()
上面已经把`BeanFactory`初始化完毕,那么这个IOC容器就接近尾声了,接下来就是一些后续工作
```java
protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
// 清除上下文级资源缓存
clearResourceCaches();
// Initialize lifecycle processor for this context.
// 为此上下文初始化生命周期处理器
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
getLifecycleProcessor().onRefresh();
// Publish the final event.
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}