前面说到SpringApplication的run方法执行时会刷新IOC容器,最终都会调AbstractApplicationContext的refresh方法。下面我们聚焦这个方法,看看容器刷新全流程是怎样的。
将refresh拆解开来分析:
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//1.刷新前的准备
prepareRefresh();
//2.让AbstractApplicationContext的子类“刷新”它内部持有的Beanfactory并返回
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//3.配置AbstractApplicationContext持有的beanFactory
prepareBeanFactory(beanFactory);
try {
//4.BeanFactory的后置处理
postProcessBeanFactory(beanFactory);
//5.调用BeanFactoryPostProcessor
invokeBeanFactoryPostProcessors(beanFactory);
//6.注册BeanPostProcessor
registerBeanPostProcessors(beanFactory);
//7.初始化国际化组件
initMessageSource();
//8.初始化事件广播器
initApplicationEventMulticaster();
//9.初始化ApplicationConext子类中其他特殊bean
onRefresh();
// 10.注册监听器
registerListeners();
// 11.初始化剩余单例Bean
finishBeanFactoryInitialization(beanFactory);
// 12.刷新后的动作
finishRefresh();
}
catch (BeansException ex) {
//处理异常
destroyBeans();
cancelRefresh(ex);
throw ex;
}
finally {
// 重置缓存
resetCommonCaches();
}
}
}
1. prepareRefresh:刷新前的准备
protected void prepareRefresh() {
//设置标志位
this.closed.set(false);
this.active.set(true);
// 初始化属性
initPropertySources();
//验证属性
getEnvironment().validateRequiredProperties();
//兼顾可重复刷新IOC容器的情况
if (this.earlyApplicationListeners == null) {
//首次刷新,把所有监听器赋值给一个新变量:早期监听器
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
// 重复刷新时,把早期监听器再赋值回所有监听器变量
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
// 早期事件集合,等待事件广播器去广播
this.earlyApplicationEvents = new LinkedHashSet<>();
}
-
初始化属性。
protected void initPropertySources() { // For subclasses: do nothing by default. }模板方法,供子类重写。前面说到ApplicationContext类体系时说到,AbstractApplicationContext的子类GenericWebApplicationContext对应注解驱动方式,子类AbstractRefreshableWebApplicationContext对应XML配置方式。
Spring Boot主要支持注解驱动,所以看下GenericWebApplicationContext的initPropertySources:
protected void initPropertySources() { ConfigurableEnvironment env = this.getEnvironment(); if (env instanceof ConfigurableWebEnvironment) { ((ConfigurableWebEnvironment)env).initPropertySources(this.servletContext,null); } }initPropertySources先获取Environment,然后调Environment的initPropertySources。我们讨论的WebApplicationType是SERVLET,对应环境具StandardServletEnvironment,它的initPropertySources:
public void initPropertySources(@Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig) { //getPropertySources返回Environment中的一个MutablePropertySources类型属性 WebApplicationContextUtils.initServletPropertySources(this.getPropertySources(), servletContext, servletConfig); }
工具类WebApplicationContextUtils:
public static void initServletPropertySources(MutablePropertySources sources, @Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig) {
Assert.notNull(sources, "'propertySources' must not be null");
String name = "servletContextInitParams";
if (servletContext != null && sources.get(name) instanceof StubPropertySource) {
sources.replace(name, new ServletContextPropertySource(name, servletContext));
}
name = "servletConfigInitParams";
if (servletConfig != null && sources.get(name) instanceof StubPropertySource) {
sources.replace(name, new ServletConfigPropertySource(name, servletConfig));
}
}
Servlet规范中,每个Servlet都可以有自己的初始化配置,ServletConfig是Servlet的配置对象,所以每个Servlet都有自己的ServletConfig;每个应用也有自己的配置,ServletContext是整个应用的配置对象,所以每个Servlet只有一个ServletContext。这里的初始化属性就是将这两种不同的配置对象设置到环境中。
2.obtainFreshBeanFactory
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
return getBeanFactory();
}
先调用refreshBeanFactory,这是模板方法,需要AbstractApplicationContext重写,
GenericWebApplicationContext的重写:
protected final void refreshBeanFactory() throws IllegalStateException {
//CAS,控制下面的部分只能执行一次
if (!this.refreshed.compareAndSet(false, true)) {
throw new IllegalStateException(
"GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
}
//只是简单的设置了beanFactory的序列化id
this.beanFactory.setSerializationId(getId());
}
AbstractRefreshableWebApplicationContext的重写:
protected final void refreshBeanFactory() throws BeansException {
//关闭前一个beanFactory(如果有的话)
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
//真正实例化一个beanFactory并加载Bean定义到beanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
loadBeanDefinitions(beanFactory);
this.beanFactory = beanFactory;
}
//catch ...
}
两种不同iApplicationContext的getBeanFactory大致相同。
3. prepareBeanFactory:预处理beanFactory
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 配置beanFactory的类加载器等
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
//注册一个BeanPostProcessor,用来处理ApplicationContext
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));
// 对LoadTimeWeaver的支持
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// 注册environment相关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());
}
}
-
ApplicationContextAwareProcessor,关注下它的回调逻辑:
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { //如果处理的bean不是下面Aware接口类型,返回。说明回调逻辑就是要处理实现了下面这些Aware接口的bean if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware || bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware || bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){ return bean; } //如果当前bean实现了这些Aware接口,就把容器applicationContext或容器的其他属性设置到后置处理器要处理的bean //Aware接口设计的意图,就是用它的的setter把框架底层的一些对象注入到要处理的bean中,供开发者使用 invokeAwareInterfaces(bean); return bean; } private void invokeAwareInterfaces(Object bean) { if (bean instanceof EnvironmentAware) { ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment()); } if (bean instanceof EmbeddedValueResolverAware) { ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver); } if (bean instanceof ResourceLoaderAware) { ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext); } if (bean instanceof ApplicationEventPublisherAware) { ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext); } if (bean instanceof MessageSourceAware) { ((MessageSourceAware) bean).setMessageSource(this.applicationContext); } if (bean instanceof ApplicationContextAware) { ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext); } }这个后置处理类已经处理了这些接口,就不用再处理了,所以下面就用beanFactory的ignoreDependencyInterface,忽略这些接口。
-
自动注入相关类。
跟进源码可看到DefaultListableBeanFactory这个IOC容器的唯一落地实现类是如何处理的。
private final Map<Class<?>, Object> resolvableDependencies; public void registerResolvableDependency(Class<?> dependencyType, @Nullable Object autowiredValue) { if (autowiredValue != null) { if (!(autowiredValue instanceof ObjectFactory) && !dependencyType.isInstance(autowiredValue)) { throw new IllegalArgumentException("Value [" + autowiredValue + "] does not implement specified dependency type [" + dependencyType.getName() + "]"); } //容器内部用了一个Map缓存被指定接口和对应实现类的映射关系 this.resolvableDependencies.put(dependencyType, autowiredValue); } } -
ApplicationListenerDetector,这个BeanPostPocessor处理事件监听器,bean初始化前加入容器,摧毁前从容器中移除:
//初始化前回调 public Object postProcessAfterInitialization(Object bean, String beanName) { if (bean instanceof ApplicationListener) { //如果处理bean是事件监听器类型ApplicationListener,且是单例,就把它加入到容器中 Boolean flag = this.singletonNames.get(beanName); if (Boolean.TRUE.equals(flag)) { this.applicationContext.addApplicationListener((ApplicationListener<?>) bean); } else if (Boolean.FALSE.equals(flag)) { this.singletonNames.remove(beanName); } } return bean; } public void addApplicationListener(ApplicationListener<?> listener) { //容器中有事件广播器对象,这个对象的有个内部类可以把监听器加入 if (this.applicationEventMulticaster != null) { this.applicationEventMulticaster.addApplicationListener(listener); } this.applicationListeners.add(listener); } //bean摧毁前回调: public void postProcessBeforeDestruction(Object bean, String beanName) { if (bean instanceof ApplicationListener) { try { //容器中的事件广播器移除监听器 ApplicationEventMulticaster multicaster = this.applicationContext.getApplicationEventMulticaster(); multicaster.removeApplicationListener((ApplicationListener<?>) bean); multicaster.removeApplicationListenerBean(beanName); } //catch... } }
4. postProcessBeanFactory:BeanFactory的后置处理
读取源码文档,这一步可以在ApplicationContext内部的beanFactory被标准初始化后修改它,这一阶段所有bean定义已经加载,但没有bean会在此实例化成一个对象。同时这一步也允许注册某些特殊的BeanPostProcessor。这个方法也是模板方法,关注下GenericWebApplicationContext,发现会向beanFactory注入Servlet相关的BeanPostProcessor和Servlet中一些域对象等。
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
if (this.servletContext != null) {
beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
}
WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext);
}
先来看看ServletContextAwareProcessor的后置处理回调逻辑,就是简单的判断如果bean是ServletContextAware类型或ServletConfigAware类型,则会把ServletContext和ServletConfig这些底层对象注入bean。
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (this.getServletContext() != null && bean instanceof ServletContextAware) {
((ServletContextAware)bean).setServletContext(this.getServletContext());
}
if (this.getServletConfig() != null && bean instanceof ServletConfigAware) {
((ServletConfigAware)bean).setServletConfig(this.getServletConfig());
}
return bean;
}
再来看WebApplicationContextUtils的registerWebApplicationScopes,发现也是简单的向beanFactory注入request、session等域对象的FactoryBean。通过FactoryBean的getObject方法可以返回对应对象。
public abstract class WebApplicationContextUtils {
public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory, @Nullable ServletContext sc) {
beanFactory.registerScope("request", new RequestScope());
beanFactory.registerScope("session", new SessionScope());
if (sc != null) {
ServletContextScope appScope = new ServletContextScope(sc);
beanFactory.registerScope("application", appScope);
sc.setAttribute(ServletContextScope.class.getName(), appScope);
}
beanFactory.registerResolvableDependency(ServletRequest.class, new WebApplicationContextUtils.RequestObjectFactory());
beanFactory.registerResolvableDependency(ServletResponse.class, new WebApplicationContextUtils.ResponseObjectFactory());
beanFactory.registerResolvableDependency(HttpSession.class, new WebApplicationContextUtils.SessionObjectFactory());
beanFactory.registerResolvableDependency(WebRequest.class, new WebApplicationContextUtils.WebRequestObjectFactory());
if (jsfPresent) {
WebApplicationContextUtils.FacesDependencyRegistrar.registerFacesDependencies(beanFactory);
}
}
//FactoryBean
private static class RequestObjectFactory implements ObjectFactory<ServletRequest>, Serializable {
public ServletRequest getObject() {
return WebApplicationContextUtils.currentRequestAttributes().getRequest();
}
}
}
最后看registerEnvironmentBeans,也是很简单的把ServletContext、ServletConfig和把它们的属性封装到Map中后注入beanFactory。
WebMvc环境中的容器,调用父类方法后,会处理手动编码的注解类和@Component标注类。
public class AnnotationConfigServletWebServerApplicationContext {
private final AnnotatedBeanDefinitionReader reader;
private final ClassPathBeanDefinitionScanner scanner;
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
super.postProcessBeanFactory(beanFactory);
if (this.basePackages != null && this.basePackages.length > 0) {
this.scanner.scan(this.basePackages);
}
if (!this.annotatedClasses.isEmpty()) {
this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));
}
}
//...
}
5.调用BeanFactory后置处理器
这部分的源码很长,反复阅读可以梳理出整体流程。直接取出beanFactory中所有BeanFactory后置处理器,然后调用代理类的同名方法:
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
}
PostProcessorRegistrationDelegate的invokeBeanFactoryPostProcessors:
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
Set<String> processedBeans = new HashSet<>();
//beanFactory是bean定义注册器
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
//用2个集合分类收集BeanFactory后置处理器
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
//BeanDefinitionRegistryPostProcessor立即回调后置处理逻辑
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
//...
} else {
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
由前面类图知道现在讨论的BeanFactory根接口的唯一落地实现类DefaultListableBeanFactory实现了BeanDefinitionRegistry,所以if判断成立。Debug时发现方法第二个参数只有3个:
这几个是创建SpringApplication对象,设置初始化器和事件监听器时加进去的,它们是初始化器或事件监听器的内部类,点开源码可见它们都是通过ConfigurableApplicationContext的addBeanFactoryPostProcessor这一途径注入到容器的。如之前所过的ConfigFileApplicationListener:
public class ConfigFileApplicationListener implements EnvironmentPostProcessor, SmartApplicationListener, Ordered {
//...
protected void addPostProcessors(ConfigurableApplicationContext context) {
context.addBeanFactoryPostProcessor(new ConfigFileApplicationListener.PropertySourceOrderingPostProcessor(context));
}
//...
}
执行到上面的if分支时,前两个被收集到registryProcessors集合,最后一个被收集到regularPostProcessors。这2个集合分别存放BeanDefinitionRegistryPostProcessor和普通的BeanFactoryPostProcessor。
继续跟踪if分支,会按照PriorityOrdered, Ordered和其他排序优先级分离**非上述途径(如开发者编写的)**获得的BeanDefinitionRegistryPostProcessor,每一优先级内再排序,然后按序执行回调方法。
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
Set<String> processedBeans = new HashSet<>();
//如果beanFactory同时是bean定义注册器
if (beanFactory instanceof BeanDefinitionRegistry) {
// ConfigurableApplicationContext的addBeanFactoryPostProcessor方法注入的BeanDefinitionRegistryPostProcessor的处理...
//非上述方式
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
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);
}
}
//排序并回调PriorityOrdered序列优先级的bean定义注册器后置处理器
//...
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);
}
}
//排序并回调Ordered序列优先级的bean定义注册器后置处理器
//...
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;
}
}
//排序并回调其他序列优先级的bean定义注册器后置处理器
//...
}
// 回调所有的postProcessBeanFactory逻辑
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
} else {
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
因为BeanDefinitionRegistryPostProcessor同时还是BeanFactoryPostProcessor,所以以上完成后还要回调上面所有的BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法,普通的BeanFactoryPostProcessor的postProcessBeanFactory方法也要回调。
到这里先整理流程再继续分析:
-
先回调ConfigurableApplicationContext的addBeanFactoryPostProcessor方法注入的BeanDefinitionRegistryPostProcessor;
-
再回调其他途径注入的BeanDefinitionRegistryPostProcessor,具体会按照不同的排序优先级依次回调;
-
再回调所有BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法;
-
最后回调ConfigurableApplicationContext的addBeanFactoryPostProcessor方法注入的普通BeanFactoryPostProcessor的postProcessBeanFactory方法。
if分支执行完毕,接着会按着处理BeanDefinitionRegistryPostProcessor的思路,对非ConfigurableApplicationContext的addBeanFactoryPostProcessor方法注入的BeanFactoryPostProcessor,按照PriorityOrdered, Ordered和其他排序优先级分离,并依次按序执行回调。ConfigurableApplicationContext的addBeanFactoryPostProcessor方式注入的没有这3种排序优先级,非这种方式有。
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
Set<String> processedBeans = new HashSet<>();
// if... else ...
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
//先收集3种不同优先级的
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);
}
}
// 再分别回调3种
}
}
所有类型的bean定义后置处理器和普通的BeanFactoryPostProcessor都处理完了,逻辑完整。这里一定要边Debug边梳理,否则容易被绕晕:
其中有个BeanDefinitionRegistryPostProcessor是处理配置类的,它是ConfigurationClassPostProcessor。Spring Boot自动装配的和开发者用@Configuration和@Component等注解注册的bean都是通过这个后置处理类完成注册到容器。
6. registerBeanPostProcessors:注册BeanPostProcessor
这部分源码看起来和BeanFactoryPostProcessor很想,也是通过PostProcessorRegistrationDelegate的静态方法实现:
protected void registerBeanPostProcessors(ConfigurableListableBeanFFF beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
继续分析:
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// 注册BeanPostProcessorChecker
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
//按照PriorityOrdered、Ordered和普通排序优先级分离BeanPostProcessor
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//PriorityOrdered类型的通过beanFactory的getBean,这里会真正初始化!
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
//单独收集MergedBeanDefinitionPostProcessore类型的BeanPostProcessor
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, priorityOrderedPostProcessors);
// 接着注册PriorityOrdered的
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String ppName : orderedPostProcessorNames) {
//同样会初始化
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
//同样收集MergedBeanDefinitionPostProcessor类型的
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// 然后注册普通的BeanPostProcessor
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);
// 最后注册上面3步收集的MergedBeanDefinitionPostProcessor类型的BeanPostProcessor
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// 再次注册ApplicationListenerDetector,这里重复注册实际是把它移到后置处理器末尾
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
7.初始化国际化组件
protected void initMessageSource() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//容器里名称是messageSource的bean,直接赋值
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
}
else {
// 没有就直接创建一个然后注册到容器
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
this.messageSource = dms;
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
}
}
8.初始化事件广播器
和初始化国际化支持的组件如出一辙,都是先检查容器里是否有响应名称的bean,有则注入,无则创建一个然后注册。
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);
}
else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
}
}
9.初始化ApplicationConext子类中其他特殊bean
模板方法,供ApplicationContext子类重写的,在单列bean实例化之前初始化一些bean。
10.注册监听器
protected void registerListeners() {
// 先把IOC容器中一组ApplicationListener对象取出,添加到事件广播器
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// 从容器中取出ApplicationListener类型bean的名称,添加到事件广播器
//这里没有用beanFactory的getBean方法获取bean对象,是为了防止监听器被过早初始化,单例bean初始化在下一动作中完成
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// 第一步的早期事件这时可以被广播了
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
11.finishBeanFactoryInitialization:初始化剩余单例Bean
11.1 getBean
先总体看一下finishBeanFactoryInitialization的实现,重点聚焦在方法最后一行。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 初始化ConversionService
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));
}
//注册一个默认的嵌入式值解析器,负责解析占位符和表达式
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// 初始化LoadTimeWeaverAware
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
beanFactory.setTempClassLoader(null);
// 冻结配置
beanFactory.freezeConfiguration();
//实例化所有非懒加载的单例bean
beanFactory.preInstantiateSingletons();
}
preInstantiateSingletons最终实现在DefaultListableBeanFactory中。点开源码,看到while死循环循环内嵌套多个do...while...循环,也是让人头大:fearful:,下面把代码折叠一下就方便分析了。在最外层while死循环的内部,先把嵌套的首层do...while...折叠一下,会发现这是用bean对象在判断,如果bean的类型不是工厂bean,就执行非工厂bean的处理逻辑。如果bean类型是工厂bean,那么bean默认不立即初始化,除非isEagerInit是true,才调用getBean初始化。首次进入while死循环,bean变量值null,肯定执行非工厂bean的逻辑。
下面展开非工厂bean对应代码,发现又是一个while死循环,内部先嵌套几层do...while...循环,再根据bean名称而不是根据bean对象判断是否工厂bean,如果是就直接获取然后退出非工厂bean的while死循环。最后又出现一个熟悉的getBean方法。先看内部的几个do...while...,如下图分析,会先执行最内部的do循环体。通常容器的beanDefinitionNames不为空,所以最内部循环体的if先不执行,直接获取第一个beanNane,然后根据这个bean名称获取bean的合并bean定义。根据这个bean定义判断,如果抽象、非单例、懒加载3个条件任何一个满足都会继续执行最内部循环体。反之那些非抽象、单例且非懒加载的bean会走出这几个do...while...,然后根据bean名称判断是否工厂bean。如果根据名称判断确实是工厂bean,会退出内层while死循环,然后继续执行工厂bean的处理逻辑,最后会继续执行最外层的while循环,重复上面的流程;如果根据名称判断不是工厂bean,那就直接getBean了。
所以最内层的嵌套do...while...只是筛选作用。
非工厂bean中那些非抽象、单例的并且非懒加载的bean,会执行getBean(beanName),进一步跟进,会调AbstractBeanFactory的方法:
public Object getBean(String name) throws BeansException {
return this.doGetBean(name, (Class)null, (Object[])null, false);
}
11.2 doGetBean
我们再跟进doGetBean的逻辑,它的内部较长,分开看。
-
循环依赖的处理
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException { //名称处理,不是关注点 String beanName = this.transformedBeanName(name); // Object sharedInstance = this.getSingleton(beanName); Object bean; if (sharedInstance != null && args == null) { //logger... bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null); }getSingleton方法会从缓存中获取当前正在获取的单例bean,和循环依赖处理有关。如果从缓存中取到,会对FactoryBean类型额外处理。
-
创建前检查和其他处理。
//...
else {
//原型bean相互依赖会引起无限循环,抛出异常
if (this.isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
//本地不存在bean定义,就让父beanFactory实例化
BeanFactory parentBeanFactory = this.getParentBeanFactory();
if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
String nameToLookup = this.originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory)parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
}
//...
return parentBeanFactory.getBean(nameToLookup);
}
-
标记当前bean已创建。
//... if (!typeCheckOnly) { this.markBeanAsCreated(beanName); } protected void markBeanAsCreated(String beanName) { if (!this.alreadyCreated.contains(beanName)) { //加锁,保证安全 synchronized(this.mergedBeanDefinitions) { if (!this.alreadyCreated.contains(beanName)) { this.clearMergedBeanDefinition(beanName); this.alreadyCreated.add(beanName); } } } }双重检查锁确保线程安全,Spring Boot中有多处使用双重检查锁的情况。
-
合并bean定义并处理@DeponsOn。
//... try { RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName); this.checkMergedBeanDefinition(mbd, beanName, args); String[] dependsOn = mbd.getDependsOn(); String[] var11; if (dependsOn != null) { var11 = dependsOn; int var12 = dependsOn.length; for(int var13 = 0; var13 < var12; ++var13) { String dep = var11[var13]; //... this.registerDependentBean(dep, beanName); try { this.getBean(dep); } //catch... } } //...Spring默认扫描包时会根据文件在文件夹位置先后顺序扫描,所以不能保证对象初始化顺序,方法或类上加上@DepondsOn后,会先初始化这个注解指定的对象。这里bean定义合并后,如果当前bean依赖了其他bean,被依赖bean中标注了@DepondsOn的先初始化,同样是用getBean方法。
-
不同域的bean的创建。
if (mbd.isSingleton()) {
sharedInstance = this.getSingleton(beanName, () -> {
try {
return this.createBean(beanName, mbd, args);
} //catch ...
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {
var11 = null;
Object prototypeInstance;
try {
this.beforePrototypeCreation(beanName);
prototypeInstance = this.createBean(beanName, mbd, args);
} finally {
this.afterPrototypeCreation(beanName);
}
bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
} else {
//其他域的bean
//...
}
根据当前bean的作用域创建对象,容器有两种域:单例sington和原型prototype,两种方式的底层都使用createBean。单例用getSingleton方法控制返回的引用唯一,原型每次会返回新的引用。每个分支最后同样对FactoryBean类型额外处理。
-
getSingleton
单例bean创建使用getSingleton方法,先从缓存中取,取到则返回,取不到就用它的第二个参数ObjectFactory的getObject方法返回单例对象,实际是用createBean创建的。
private final Map<String, Object> singletonObjects = new ConcurrentHashMap(256); public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(beanName, "Bean name must not be null"); synchronized(this.singletonObjects) { //从缓存中取不到 Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { //... //控制循环依赖 this.beforeSingletonCreation(beanName); boolean newSingleton = false; try { //缓存中取不到直接创建 singletonObject = singletonFactory.getObject(); newSingleton = true; } //catch... } finally { this.afterSingletonCreation(beanName); } //创建好的bean放缓存 if (newSingleton) { this.addSingleton(beanName, singletonObject); } } return singletonObject; } }singletonFactory只是简单的函数式接口,singletonObject是createBean方法的执行结果。
@FunctionalInterface public interface ObjectFactory<T> { T getObject() throws BeansException; }
11.3 createBean
两个处理点,通过resolveBeforeInstantiation创建对象和通过doCreateBean。
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;
Class<?> resolvedClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
//...
Object beanInstance;
try {
beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
if (beanInstance != null) {
return beanInstance;
}
} // catch...
try {
beanInstance = this.doCreateBean(beanName, mbdToUse, args);
return beanInstance;
} // catch...
}
resolveBeforeInstantiation分两步,先执行所有的InstantiationAwareBeanPostProcessor的初始化前逻辑生成对象,如果生成成功,就用所有的BeanPostProcessor的初始化后回调逻辑处理对象。
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = this.determineTargetType(beanName, mbd);
if (targetType != null) {
//执行所有的InstantiationAwareBeanPostProcessor的初始化前回调逻辑生成bean
bean = this.applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
//如果生成成功再执行初始化后回调
bean = this.applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = bean != null;
}
return bean;
}
如果resolveBeforeInstantiation没有创建出对象,需要用doCreateBean创建。
11.4 doCreateBean
doCreateBean方法执行3个逻辑:实列化bean、属性赋值和bean对象初始化。
11.4.1 实例化bean
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
BeanWrapper instanceWrapper = null;
//...
if (instanceWrapper == null) {
//调createBeanInstance方法实例化bean
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
//...
1. 先校验要创建的bean是否可访问:
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
Class<?> beanClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
// throw ...
}
- 再用工厂方法创建
//...
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return this.obtainFromSupplier(instanceSupplier, beanName);
} else if (mbd.getFactoryMethodName() != null) {
return this.instantiateUsingFactoryMethod(beanName, mbd, args);
}
函数式接口Supplier可以完成bean对象创建,看一个案例:
先用@Component标注一个将要注册到容器中的bean。
package org.cosmos.springboot.induction.demo;
import org.springframework.stereotype.Component;
@Component
public class DemoBean {
private String name;
public DemoBean(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
再定义一个BeanFactoryPostProcessor用来提供创建bean的Supplier,Supplier可以自定义创建对象:
package org.cosmos.springboot.induction.demo;
@Component
public class SupplierBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
BeanDefinition demoBean = beanFactory.getBeanDefinition("demoBean");
GenericBeanDefinition genericBeanDefinition = (GenericBeanDefinition) demoBean;
genericBeanDefinition.setInstanceSupplier(() -> new DemoBean("demo"));
genericBeanDefinition.setBeanClass(DemoBean.class);
}
}
执行主启动类的main:
package org.cosmos.springboot.induction.demo;
@SpringBootApplication
public class SpringBootInductionApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootInductionApplication.class, args);
}
}
结果:
- 利用构造方法实例化bean。
基本流程是推断构造方法、构造方法参数注入、反射调构造方法创建对象。这里对于原型bean会在根bean定义中构造器参数,提高多次利用同一构造器创建对象的效率。
//...
else {
//构造器是否缓存
boolean resolved = false;
//是否需要给构造方法参数注入值
//比如当前BeanDefinition用的是无参构造方法,那么autowireNecessary为false,否则为true
boolean autowireNecessary = false;
if (args == null) {
synchronized(mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
//构造器被缓存了
if (resolved) {
//如果需要给构造方法参数注入值,就用缓存的参数注入构造器去实例化bean
//否则代表无参构造器,直接实例化
return autowireNecessary ? this.autowireConstructor(beanName, mbd, (Constructor[])null, (Object[])null) : this.instantiateBean(beanName, mbd);
} else {
//构造器没被缓存,利用SmartInstantiationAwareBeanPostProcessor推断出构造器,这里也提供了一个扩展点
Constructor<?>[] ctors = this.determineConstructorsFromBeanPostProcessors(beanClass, beanName);
// 没有推断出且满足:配置的构造器自动注入参数方式不为AUTOWIRE_CONSTRUCTOR;
//且没通过Bean定义指定构造方法参数值;
//且调用getBean的时候没传入构造方法参数值
if (ctors == null && mbd.getResolvedAutowireMode() != 3 && !mbd.hasConstructorArgumentValues() && ObjectUtils.isEmpty(args)) {
//采用首选的构造器,使用了@Primary注解的为首选的
ctors = mbd.getPreferredConstructors();
//存在首选构造器,就去去实例化bean,否则用默认无参构造器实例bean
return ctors != null ? this.autowireConstructor(beanName, mbd, ctors, (Object[])null) : this.instantiateBean(beanName, mbd);
} else {
//以上情况不满足(推断出了构造器,或构造器注入方式AUTOWIRE_CONSTRUCTOR,或bean定义指定了参数,或getBean时传进来了参数),则构造参数直接注入创建bean
return this.autowireConstructor(beanName, mbd, ctors, args);
}
}
}
到这里createBeanInstance实例化了bean,但没给属性赋值。
11.4.2 属性赋值前合并
//...
synchronized(mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
} // catch ...
mbd.postProcessed = true;
}
}
applyMergedBeanDefinitionPostProcessors调容器中所有MergedBeanDefinitionPostProcessor,这里关注
InitDestroyAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor和AutowiredAnnotationBeanPostProcessor。
以InitDestroyAnnotationBeanPostProcessor为例观察下:
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
InitDestroyAnnotationBeanPostProcessor.LifecycleMetadata metadata = this.findLifecycleMetadata(beanType);
metadata.checkConfigMembers(beanDefinition);
}
findLifecycleMetadata会调buildLifecycleMetadata,会收集当前创建的bean中标注了@PostConstruct和@PreDestroy的方法:
private InitDestroyAnnotationBeanPostProcessor.LifecycleMetadata buildLifecycleMetadata(Class<?> clazz) {
//...
List<InitDestroyAnnotationBeanPostProcessor.LifecycleElement> initMethods = new ArrayList();
List<InitDestroyAnnotationBeanPostProcessor.LifecycleElement> destroyMethods = new ArrayList();
Class targetClass = clazz;
do {
List<InitDestroyAnnotationBeanPostProcessor.LifecycleElement> currInitMethods = new ArrayList();
List<InitDestroyAnnotationBeanPostProcessor.LifecycleElement> currDestroyMethods = new ArrayList();
//反射处理2种方法
ReflectionUtils.doWithLocalMethods(targetClass, (method) -> {
if (this.initAnnotationType != null && method.isAnnotationPresent(this.initAnnotationType)) {
InitDestroyAnnotationBeanPostProcessor.LifecycleElement element = new InitDestroyAnnotationBeanPostProcessor.LifecycleElement(method);
currInitMethods.add(element);
}
if (this.destroyAnnotationType != null && method.isAnnotationPresent(this.destroyAnnotationType)) {
currDestroyMethods.add(new InitDestroyAnnotationBeanPostProcessor.LifecycleElement(method));
}
});
//...
} while(targetClass != null && targetClass != Object.class);
//return ...
}
}
其他2种后置处理器逻辑大致相同,只是收集注解种类不同而已。
后面有对早期单例bean引用获取与缓存:
//...
boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
if (earlySingletonExposure) {
//与解决循环依赖有关
this.addSingletonFactory(beanName, () -> {
return this.getEarlyBeanReference(beanName, mbd, bean);
});
}
11.4.3 属性赋值populateBean
try {
this.populateBean(beanName, mbd, instanceWrapper);
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
} //catch...
看下populateBean的逻辑。
- 回调InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation逻辑。
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
//...
if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
Iterator var4 = this.getBeanPostProcessors().iterator();
while(var4.hasNext()) {
BeanPostProcessor bp = (BeanPostProcessor)var4.next();
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
}
- 回调InstantiationAwareBeanPostProcessor的postProcessProperties逻辑。
//...
Iterator var9 = this.getBeanPostProcessors().iterator();
while(var9.hasNext()) {
BeanPostProcessor bp = (BeanPostProcessor)var9.next();
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
PropertyValues pvsToUse = ibp.postProcessProperties((PropertyValues)pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
//...
pvsToUse = ibp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName);
//...
}
//...
}
}
以CommonAnnotationBeanPostProcessor为例看下:
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs);
try {
metadata.inject(bean, beanName, pvs);
} //catch ...
return pvs;
}
findResourceMetadata会调用buildResourceMetadata收集@Resource等。
private InjectionMetadata buildResourceMetadata(final Class<?> clazz) {
//...
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
Class<?> targetClass = clazz;
do {
final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
//反射获取注解标注的字段
ReflectionUtils.doWithLocalFields(targetClass, field -> {
if (webServiceRefClass != null && field.isAnnotationPresent(webServiceRefClass)) {
//判断...
currElements.add(new WebServiceRefElement(field, field, null));
}
else if (ejbClass != null && field.isAnnotationPresent(ejbClass)) {
//判断...
currElements.add(new EjbRefElement(field, field, null));
}
else if (field.isAnnotationPresent(Resource.class)) {
//判断...
if (!this.ignoredResourceTypes.contains(field.getType().getName())) {
currElements.add(new ResourceElement(field, field, null));
}
}
});
//反射获取注解标注的方法...
}
while (targetClass != null && targetClass != Object.class);
// return ...
}
收集好封装成元数据对象,然后用反射设置当前bean的属性值。
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Collection<InjectionMetadata.InjectedElement> checkedElements = this.checkedElements;
//所有需要注入的信息
Collection<InjectionMetadata.InjectedElement> elementsToIterate = checkedElements != null ? checkedElements : this.injectedElements;
if (!((Collection)elementsToIterate).isEmpty()) {
Iterator var6 = ((Collection)elementsToIterate).iterator();
while(var6.hasNext()) {
InjectionMetadata.InjectedElement element = (InjectionMetadata.InjectedElement)var6.next();
//利用反射将需要注入到的其他bean对象设置成为当前创建bean的成员属性
element.inject(target, beanName, pvs);
}
}
}
-
属性赋值动作
//... if (pvs != null) { //前面步骤生成的PropertyValues封装了当前bean的所有属性值,这里把它设置到bean中 this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs); }
11.3.4 对象初始化initializeBean
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
//if ...
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 ...
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
-
invokeAwareMethods:
private void invokeAwareMethods(String beanName, Object bean) { if (bean instanceof Aware) { if (bean instanceof BeanNameAware) { ((BeanNameAware)bean).setBeanName(beanName); } if (bean instanceof BeanClassLoaderAware) { ClassLoader bcl = this.getBeanClassLoader(); if (bcl != null) { ((BeanClassLoaderAware)bean).setBeanClassLoader(bcl); } } if (bean instanceof BeanFactoryAware) { ((BeanFactoryAware)bean).setBeanFactory(this); } } }在prepareBeanFactory中,就注册一个ApplicationContextAwareProcessor,它的postProcessBeforeInitialization用来处理ApplicationContext有关的Aware接口。这里是其他几个Aware接口的处理。
-
applyBeanPostProcessorsBeforeInitialization
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; Object current; for(Iterator var4 = this.getBeanPostProcessors().iterator(); var4.hasNext(); result = current) { BeanPostProcessor processor = (BeanPostProcessor)var4.next(); current = processor.postProcessBeforeInitialization(result, beanName); if (current == null) { return result; } } return result; }执行所有BeanPostProcessor的初始化前方法,包括上面说的ApplicationContextAwareProcessor设置ApplicationContxt到当前bean中,也包括InitDestroyAnnotationBeanPostProcessor回调bean中标注的@PostConstruct等方法。
3.invokeInitMethods
init-method和InitializingBean接口调用,我们最熟悉的实现InitializingBean接口并重写afterPropertiesSet方法就只是在这里被处理的:
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd) throws Throwable { boolean isInitializingBean = bean instanceof InitializingBean; if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) { //if ... else { ((InitializingBean)bean).afterPropertiesSet(); } } if (mbd != null && bean.getClass() != NullBean.class) { String initMethodName = mbd.getInitMethodName(); if (StringUtils.hasLength(initMethodName) && (!isInitializingBean || !"afterPropertiesSet".equals(initMethodName)) && !mbd.isExternallyManagedInitMethod(initMethodName)) { this.invokeCustomInitMethod(beanName, bean, mbd); } } }-
applyBeanPostProcessorsAfterInitialization:
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; Object current; for(Iterator var4 = this.getBeanPostProcessors().iterator(); var4.hasNext(); result = current) { BeanPostProcessor processor = (BeanPostProcessor)var4.next(); current = processor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } } return result; }
-
执行所有BeanPostProcessor的初始化后方法,如prepareBeanFactory中注册的ApplicationListenerDetector,它的初始化后方法会移除所有监听器。还要关注下AbstractAutoProxyCreator,和AOP有关,bean本身创建后根据需要创建代理对象:
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return this.wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
}
createBean中扩展点很多,我们来看下InstantiationAwareBeanPostProcessor,它继承了BeanPostProcessor,获得了父类的初始化前方法和初始化后方法,同时它本身又加了实例化前和实例化后以及属性注入前处理方法。Instantiation是实例化,Initialization是初始化。看一个案例:
1.DemoController类有2个属性:字符串creator,DemoService类型demoService,DemoController有一个无参构造:
package org.cosmos.springboot.induction.demo.processor;
@RestController
public class DemoController {
private String creator = "c1";
private DemoService demoService;
public String getCreator() {
return creator;
}
public void setCreator(String creator) {
this.creator = creator;
System.out.println("--DemoController内的creator被注入--");
}
@Autowired
public void setDemoService(DemoService demoService) {
this.demoService = demoService;
System.out.println("--DemoController内的demoService被注入--");
}
public DemoController() {
System.out.println("--DemoController无参构造被执行--");
}
}
2.demoService:有一个无参构造
package org.cosmos.springboot.induction.demo.processor;
@Service
public class DemoService {
public DemoService() {
System.out.println("--DemoService无参构造被执行--");
}
}
-
定义一个InstantiationAwareBeanPostProcessor,重写5个回调方法:
package org.cosmos.springboot.induction.demo.processor; @Component public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor { //实例化前 @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { if (beanName.equals("demoController")){ System.out.println("--postProcessBeforeInstantiation被执行--"); } return null; } //实例化后:这个方法返回后才能继续 @Override public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { if (beanName.equals("demoController")){ System.out.println("--postProcessAfterInstantiation被执行--"); } return true; } //属性注入前 @Override public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException { if (beanName.equals("demoController")){ System.out.println("--postProcessProperties被执行前--"); MutablePropertyValues mutablePropertyValues = new MutablePropertyValues(); mutablePropertyValues.addPropertyValue("creator", "c2"); pvs = mutablePropertyValues; } return pvs; } //初始化前 @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (beanName.equals("demoController")){ System.out.println("--postProcessBeforeInitialization--" + beanName); } return bean; } //初始化后 @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (beanName.equals("demoController")){ System.out.println("--postProcessAfterInitialization--" + beanName); } return bean; } }4.测试类:
package org.cosmos.springboot.induction.demo.processor; public class Test { public static void main(String[] args) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext("org.cosmos.springboot.induction.demo.processor"); DemoController bean = ctx.getBean(DemoController.class); System.out.println("----" + bean.getCreator()); } }结果:
分析:
AnnotationConfigApplicationContext构造方法参数传入要扫描的包路径,先调无参构造去初始化注解类定义读取器和类路径包扫描器,然后refresh去刷寻IOC容器:
public AnnotationConfigApplicationContext(String... basePackages) {
this();
scan(basePackages);
refresh();
}
public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
refresh执行到finishBeanFactoryInitialization时,先用getBean获取DemoController。
执行到createBean时先用resolveBeforeInstantiation创建对象,很明显本例中MyInstantiationAwareBeanPostProcessor的实例化前回调方法返回了null,所以它的实例化后方法也没回调,继续用doCreateBean创建对象。在实例化bean阶段,用构造方法创建了DemoController,日志也显示出来确实掉了DemoController的无参构造。bean实例化好后要属性赋值,先执行populateBean,这里会先回调InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation,再回调它的的postProcessProperties。postProcessAfterInstantiation把DemoController的属性creator从"c1"设置成了"c2",同时要把demoService注入,这就触发了DemoService对象的创建。结果可以看到DemoService的无参构造接着执行了。demoService对象创建成功就会注入到DemoController,setter跟着执行,"c2"也被注入给creator。最后执行DemoController的初始化方法initializeBean,分别执行初始化前和初始化后方法。测试类最后执行getBean获取DemoController的creator属性证实了我们的干涉生效了。
这个案例说明了Spring Boot留给开发者的扩展点是非常有用的,我们可以在bean的生命周期中加上自定义逻辑。
所有懒加载单例bean全部初始化后,回到preInstantiateSingletons,最内层循环会处理所有实现了SmartInitializingSingleton的bean,回调它的afterSingletonsInstantiated。这也是提供出来的一个扩展点,作用和SpringApplication执行run方法提供的ApplicationRunner和CommandLineRunner类似。
12.finishRefresh:刷新后动作
protected void finishRefresh() {
//清除资源缓存
clearResourceCaches();
// Initialize lifecycle processor for this context.
//初始化ApplicationContext的LifecycleProcessor
initLifecycleProcessor();
// 回调LifecycleProcessor
getLifecycleProcessor().onRefresh();
// 发布容器刷新完成事件
publishEvent(new ContextRefreshedEvent(this));
LiveBeansView.registerApplicationContext(this);
}
所有非懒加载单例bean初始化后的动作,通过Lifecycle提供了一个新的切入点,可在容器启动和停止时触发它的start方法和stop方法。