初始化12步骤
容器创建会进入 refresh 方法,总共 12 个步骤
// org.springframework.context.support.AbstractApplicationContext#refresh
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// 步骤一:准备阶段
prepareRefresh();
// 步骤二:获得一个 BeanFactory(bean 定义信息在这一步会保存好)
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 步骤三:给 BeanFactory 赋能
prepareBeanFactory(beanFactory);
try {
// 步骤四:扩展 BeanFactory(这是个钩子方法,目的是留给子类的,子类可根据需要再次赋予 BeanFactory 更多能力)
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// 步骤五:执行 BeanFactoryProPercessor
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
...
}
}
步骤1:准备容器
// org.springframework.context.support.AbstractApplicationContext#prepareRefresh
protected void prepareRefresh() {
// 计时
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
// 这是一个模板方法,子类复写自定义配置 spring 信息,MVC、Boot、Cloud 等很多框架都复写过
initPropertySources();
// 必要参数验证
getEnvironment().validateRequiredProperties();
// 初始化事件监听器和事件,都置为空列表
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
this.earlyApplicationEvents = new LinkedHashSet<>();
}
步骤2:获得 BeanFactory
- 产生一个新鲜的 BeanFactory
- 保存好 bean 定义信息
ApplicationContext 一般叫容器,BeanFactory 是真正保存 bean 的地方
// org.springframework.context.support.AbstractApplicationContext#obtainFreshBeanFactory
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
return getBeanFactory();
}
// org.springframework.context.support.AbstractRefreshableApplicationContext#refreshBeanFactory
@Override
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
// 这里会把 bean 定义信息准备好
loadBeanDefinitions(beanFactory);
this.beanFactory = beanFactory;
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
步骤3:初始化 BeanFactory
上一步刚初始化了 BeanFactory,还没什么能力,这一步是配置 BeanFactory 的属性,让其具有处理某些动作的能力
当遇到相关动作,就会使用这里赋予的能力,所以这里代码比较简单,就是给不同属性赋值
- 比如 addBeanPostProcessor 给 BeanFactory 添加了一些后置处理器
- 加入到 beanPostProcessors 属性中
- 比如 SPEL 解析器,各种 Aware 回调处理器
- 比如 ignoreDependencyInterface 忽略了一些自动装配的类
- 加入到 ignoredDependencyInterfaces 属性中
- 1,这些接口的实现类的属性@Autowired 不生效(不能注入别的 bean)
- 2,别的 bean 里也使用 @Autowired 给属性赋值也不生效(不能被别的 bean 注入)
- 比如 registerResolvableDependency 提前放入一些可能需要别的依赖的 bean
- 是加入到 resolvableDependencies 属性中
- 这一步是为了提升效率的,如果不提前放,后面找到这些 bean 也会放进去(事先就放进去)
// org.springframework.context.support.AbstractApplicationContext#prepareBeanFactory
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 类加载器
beanFactory.setBeanClassLoader(getClassLoader());
// 是否不解析 SPEL,spring.spel.ignore 配置项来控制
if (!shouldIgnoreSpel) {
// StandardBeanExpressionResolver:SPEL 表达式解析器
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
}
// ResourceEditorRegistrar:用于把配置文件转成一个 Resource 对象
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 添加后置处理器,如果有 bean 实现了 ApplicationContextAware,BeanFactory 使用 ApplicationContextAwareProcessor 去处理
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.ignoreDependencyInterface(ApplicationStartupAware.class);
// 这些注册为 bean,比如可以直接 @Autorired BeanFactory beanFactory 来注入 BeanFactory
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// 添加后置处理器,让 BeanFactory 可以处理时间发布与监听
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// GraalVM 支持,java 虚拟机一般都是 hotspot VM
if (!NativeDetector.inNativeImage() && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// 再实现注册一些默认的 bean
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
}
}
步骤4:扩展 BeanFactory
上一步已经赋能了,这里再次赋能,这是一个钩子方法,没有实现,所以专门提供给子类的
比如 SpringMVC 扩展后我们标注 @Controller 就会把这个 bean 注入到容器中
步骤5:执行 BeanFactoryPostProcesser
步骤 3 给 BeanFactory 放入了一批后置处理器,这一步就是要执行他们
// org.springframework.context.support.AbstractApplicationContext#invokeBeanFactoryPostProcessors
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// this.getBeanFactoryPostProcessors() 就是获取所有 bean 工厂后置处理器,此时是空的 invokeBeanFactoryPostProcessors 会去找
// invokeBeanFactoryPostProcessors 首先找到所有实现了 BeanFactoryPostProcessor 接口的 bean,然后挨个调用其 postProcessBeanFactory 方法
// BeanFactoryPostProcessor 干嘛的?修改 bean 定义的,在创建前对 bean 定义做一些修改,后续根据修改后的定义来创建 bean
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors());
// GraalVM 支持
if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean("loadTimeWeaver")) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
// org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, java.util.List<org.springframework.beans.factory.config.BeanFactoryPostProcessor>)
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
...
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)) {
// 找到所有实现了 BeanFactoryPostProcessor 的类
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
...
}
标签:BeanFactory,流程,beanFactory,bean,启动,context,new,IOC,class
From: https://www.cnblogs.com/cyrushuang/p/18502280