Spring:Bean生命周期

bean的生命周期

Spring容器技术内幕

如果Spring容器是一辆汽车,那么BeanFactory是汽车的发动机,而ApplicationContext是一辆完整的汽车。

Spring以容器管理所有的bean对象,容器的实体是一个BeanFactory对象。但我们常用的容器是另一个ApplicationContext,它在内部持有了BeanFactory,所有和BeanFactory相关的操作都会委托给内部的BeanFactory来完成。

ApplicationContext是一个接口,默认的实现类是AnnotationConfigApplicationContext,基于注解实现。另一种是ClassPathXmlApplicationContext,基于xml使用。

Bean生命周期控制

Bean生命周期由多个特定的生命周期阶段组成,每个生命阶段都开放了接口,允许外界对Bean施加控制。

Spring对对象的可扩展性主要就是依靠InstantiationAwareBeanPostProcessor和BeanPostProcessor来实现的。

  • InstantiationAwareBeanPostProcessor。主要是作用于实例化阶段。
  • BeanPostProcessor。主要作用于初始化阶段。

在Spring中可以从两个层面定义Spring的生命周期:

  • Bean的作用范围。
  • 实例化Bean时所经历的一系列阶段。

启动流程

  • Application refresh:
    • BeanFactory初始化。
    • 生命周期控制。

概念

构造函数 –> 依赖注入 –> init-method

实例化,使用构造器:

  • IOC功能需要是利用反射原理,反射获取类的无参构造方法创建对象,如果一个类没有无参的构造方法spring是不会创建对象的。

初始化 init-method。

  • 只有一个类完整的实例被创建出来后,才能走初始化方法。

BeanFactory

是什么

BeanFactory可以理解为是个HashMap,key为BeanName,Value就是Bean的实例,并通常只提供注册(put)、获取(get)功能。

协作

如果没有特殊指定,默认采用延迟初始化策略(lazy-load)。只有当客户端对象需要访问容器中的某个受管对象的时候,才对该受管对象进行初始化以及依赖注入操作。所以,相对来说,容器启动初期速度较快,所需 要的资源有限。对于资源有限,并且功能要求不是很严格的场景,BeanFactory是比较合适的IoC容器选择。

我们先来看一下BeanFactory类的关系图(如下所示):

img

BeanDefinition

实现Bean的定义(即对象的定义),且完成了对依赖的定义。BeanDefinition是配置文件<bean>元素标签在容器中的内部表示。

最重要的部分就是BeanDefinition,它完成了Bean的生成过程。一般情况下我们都是通过配置文件(xml,properties)的方式对bean进行配置,每种文件都需要实现BeanDefinitionReader,因此是reader本身现了配置文字 到bean对象的转换过程。当然我们自己也可以实现任意格式的配置文件,只需要自己来实现reader即可。

BeanDefinitionRegistry

将定义好的bean,注册到容器中(此时会生成一个注册码)。

BeanFactory

是一个bean工厂类,从中可以取到任意定义过的bean。

原理

启动容器:

1566788251168

了解BeanFactory当中的Bean生命周期:

1566524237041

  1. 当调用者通过getBean(beanName)向容器请求某一个Bean时,如果容器注册了org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor接口,则在实例化Bean前,调用postProcessBeforeInstantiation()
  2. 根据配置情况调用Bean构造函数或工厂方法实例化Bean。
  3. 如果容器注册了InstantiationAwareBeanPostProcessor接口,那么在实例化Bean之后,调用该接口的postProcessAfterInstantiation()方法,可在这里对已经实例化的对象进行装饰。
  4. 如果Bean配置了属性信息,那么容器将在这一步将配置值设置到Bean对应的属性中,不过在设置每个属性前将先调用InstntiationAwareBeanPostProcessor接口的postProcessPropertyValues()
  5. 调用Bean的属性设置方法设置属性值。
  6. 如果Bean实现了org.springframework.beans.factory.BeanNameAware接口,则将调用setBeanName()接口方法,将配置文件中该Bean对应的名称设置到Bean中。
  7. 如果Bean实现了org.springframework.beans.factory.BeanFactoryAware接口,则将调用setBeanFactory(),将BeanFactory容器实例设置到Bean中。
  8. 如果BeanFactory装配了org.springframework.beans.factory.config.BeanPostProcessor后处理器,则将调用BeanPostProcess的Object postProcessBeforeInitialization(Object bean,string beanName)对Bean进行加工操作。
    • 入参bean是当前正在处理的Bean,beanName是当前Bean的配置名。返回加工处理后的Bean。
    • 该操作可以对某些Bean进行特殊的处理甚至改变Bean的行为,其为容器提供对Bean进行后续加工处理的切入点。AOP、动态代理都通过BeanPostProcessor实现。
  9. 如果Bean实现了InitializingBean接口,则将调用接口的afterPropertiesSet()方法。
  10. 如果在<bean>中通过init-method属性定义了初始化方法,则将执行该方法。
  11. BeanPostProcessor后处理器的Object postProcessAfterInitialization(Object bean,String beanName),这个方法此时调用容器再次获得对Bean进行加工处理的机会。
  12. 如果在<bean>中指定Bean的作用范围为prototype,则将Bean返回给调用者,调用者负责Bean后续生命的管理,Spring不再管理这个Bean的生命周期。如果作用范围为singleton则将Bean放入Spring IOC的缓冲池中并将Bean引用返回给调用者,Spring继续对这些Bean进行后续的生命管理。
  13. 对于singleton的Bean,当容器关闭时将触发Spring对Bean后续生命周期的管理工作。如果Bean实现了DisposableBean接口,则将调用接口的destory(),可以在此编写释放资源、记录日志等操作。
  14. 对于singleton的Bean,如果通过<bean>的destroy-method属性指定了Bean的销毁方法,则Spring会执行Bean的这个方法,完成资源的释放等操作。

源码

BeanFactory.getBean()

注册Bean。

1552554776007

  1. Spring对bean进行实例化;
  2. Spring将值和bean的引用注入到bean对应的属性中;
  3. 如果bean实现了BeanNameAware接口,Spring将bean的ID传递给setBean-Name()方法;
  4. 如果bean实现了BeanFactoryAware接口,Spring将调setBeanFactory()方法,将BeanFactory容器实例传入;
  5. 如果bean实现了ApplicationContextAware接口,Spring将调用setApplicationContext()方法,将bean所在的应用上下文的引用传入进来;
  6. 如果bean实现了BeanPostProcessor接口,Spring将调用它们的post-ProcessBeforeInitialization()方法;
  7. 如果bean实现了InitializingBean接口,Spring将调用它们的after-PropertiesSet()方法。类似地,如果bean使用init-method声明了初始化方法,该方法也会被调用;
  8. 如果bean实现了BeanPostProcessor接口,Spring将调用它们的post-ProcessAfterInitialization()方法;
  9. 此时,bean已经准备就绪,可以被应用程序使用了,它们将一直驻留在应用上下文中,直到该应用上下文被销毁;
  10. 如果bean实现了DisposableBean接口,Spring将调用它的destroy()接口方法。同样,如果bean使用destroy-method声明了销毁方法,该方法也会被调用。

Bean生成

Bean的生成大致可以分为两个阶段,容器启动阶段和bean实例化阶段:

img

容器启动阶段

只完成bean的定义:

  • 加载配置文件(通常是xml文件)。
  • 通过reader生成beandefinition。
  • beanDefinition注册到beanDefinitionRegistry。

bean实例化阶段

完成bean的初始化:

  • 当某个bean被getBean()调用时。
  • bean需要完成初时化,以及其依赖对象的初始化。
  • 如果bean本身有回调,还需要调用其相应的回调函数。

Spring Ioc在初始化完成之后,给了我们提供一些方法,让我们来改变一些bean的定义org.springframework.beans.factory.config.PropertyPlaceholderConfigurer:使我们可能通过配置文件的形式,配置一些参数:

  • PropertyOverrideConfigurer:则可以覆盖原本的bean参数。
  • CustomEditorConfigurer:则提供类型转换支持(配置文件都是string,它需要知道转换成何种类型)。

Bean的初始化过程

img

如果你认为实例化的对象就是通过我们定义的类new 出来的,那就大错特错了,其实这里用到了AOP机制,生成了其代理对象(通过反射机制生成接口对象,或者是通过CGLIB生成子对象)。

  • bean的具体装载过程是由beanWrapper实现的,它继承了PropertyAccessor (可以对属性进行访问)、PropertyEditorRegistry 和TypeConverter接口 (实现类型转换,就上前面说的)。
  • 完成设置对象属性之后,则会检查是否实现了Aware类型的接口,如果实现了,则主动加载。
  • BeanPostprocessor 可以帮助完成在初始化bean之前或之后 帮我们完成一些必要工作,比如我们在连接数据库之前将密码存放在一个加密文件,当我们连接数据库之前,需要将密码进行加载解密。只要实现 相应的接口即可:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public interface BeanPostProcessor {

/**
* Apply this BeanPostProcessor to the given new bean instance <i>before</i> any bean
* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
* or a custom init-method). The bean will already be populated with property values.
* The returned bean instance may be a wrapper around the original.
* @param bean the new bean instance
* @param beanName the name of the bean
* @return the bean instance to use, either the original or a wrapped one; if
* {@code null}, no subsequent BeanPostProcessors will be invoked
* @throws org.springframework.beans.BeansException in case of errors
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
*/
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;

/**
* Apply this BeanPostProcessor to the given new bean instance <i>after</i> any bean
* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
* or a custom init-method). The bean will already be populated with property values.
* The returned bean instance may be a wrapper around the original.
* <p>In case of a FactoryBean, this callback will be invoked for both the FactoryBean
* instance and the objects created by the FactoryBean (as of Spring 2.0). The
* post-processor can decide whether to apply to either the FactoryBean or created
* objects or both through corresponding {@code bean instanceof FactoryBean} checks.
* <p>This callback will also be invoked after a short-circuiting triggered by a
* {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method,
* in contrast to all other BeanPostProcessor callbacks.
* @param bean the new bean instance
* @param beanName the name of the bean
* @return the bean instance to use, either the original or a wrapped one; if
* {@code null}, no subsequent BeanPostProcessors will be invoked
* @throws org.springframework.beans.BeansException in case of errors
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
* @see org.springframework.beans.factory.FactoryBean
*/
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;

}
  • 在完成postProcessor之后,则会看对象是否定义了InitializingBean 接口,如果是,则会调用其afterProper- tiesSet()方法进一步调整对象实例的状态 ,这种方式并不常见。spring还提供了另外一种指定初始化的方式,即在bean定义中指定init-method 。
  • 当这一切完成之后,还可以指定对象销毁 的一些回调,比如数据库的连接池的配置,则销毁前需要关闭连接等。相应的可以实现DisposableBean 接口或指定destroy-method。

InstantiationStrategy

InstantiationStrategy负责根据BeanDefinition对象创建一个Bean实例。

BeanWrapper

BeanWrapper相对于一个代理器,Spring委托BeanWrapper完成Bean属性的填充工作,在Bean实例被创建出来后,容器主控程序将Bean实例通过BeanWrapper保证起来。

Spring对Bean的影响

在Spring的完整生命周期当中,经过许多关键点,每个关键点涉及特定的方法调用,可大概划分为:

  • Bean自身的方法。
    • Bean自身的构造函数实例化、Setter设置Bean的属性值,init-method与destroy-method。
  • Bean级生命周期接口方法。由Bean类直接实现:
    • BeanNameAware。BeanFactory。InitializingBean。DisposableBean。等。
  • 容器级生命周期接口方法。
    • InstantiationAwareBeanPostProcessor与BeanPostProcessor接口,它们的实现类一般称为后处理器。
    • 后处理器接口一般不由Bean自身实现,它们独立于Bean,实现类以容器附加装置的形式注册到Spring容器,通过接口反射为Spring容器扫描识别,在创建任何Bean时后处理器都会发生作用,即是全局范围影响。
    • 也可以限定其对某一部分的Bean处理。
  • 工厂后处理器接口方法。
    • AspectJWeavingEnabler、CustomAutowrieConfigurer、ConfigurationClassPostProcessor等方法。
    • 也是容器级,在应用上下文装载配置文件后立即调用。

在整个生命周期当中,Spring对Bean产生的影响主要是在两个级别上:即容器处理与类本身处理。

  • 容器级别。
    • InstantiationAwareBeanPostProcessor。
    • BeanPostProcessor。
      • 可以像插件一样注册到Spring容器,为容器提供额外的功能。
  • 类本身级别。
    • Constructor。
    • init-method。
      • 通过bean的init-method指定的初始化方法。需要在bean的配置文件中配置。
    • setter。
    • destroy-method。
  • 类实现接口级别。需要Bean自身去实现这些接口。
    • BeanNameAware。将配置文件中该Bean对应的名称设置到Bean中。
    • BeanFactory。将BeanFactory容器实例设置到Bean中。
    • InitializingBean。
    • DisposableBean。在容器销毁后,对Bean进行后续处理操作。
    • 其实不会使用这个东西。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter{
//接口方法,在实例化Bean前调用。
public Object postProcessBeforeInstantiation(Class beanClass,String beanName) throws BeansException{
if("cars".equals(beanName)){
sout("bean cars")
}
return null
}

//在设置某个属性时调用。
public PropertyValues postProcessPropertyValues(PropertyValues pvs,PropertyDescriptor[] pds,Object bean,String beanName) throws BeansException{
if("cars".equals(beanName)){
sout(propervalues);
}
return pvs;
}
}

Bean生命周期接口

使用Bean生命周期接口对Bean进行额外控制,虽然让Bean具有了更细致的生命周期阶段,但也使得Bean和Spring框架紧密地绑定在一起。

因此如果用户希望将业务完全POJO化,则可以只实现自己的业务接口,不需要与某个特定框架的接口关联。

可以通过<bean>的init-method和destroy-method属性配置方式为Bean指定初始化和销毁的方法。该方法与通过实现InitializingBean和DisposableBean接口达到的效果是完全相同的。

前者的实现方式可以使得Bean不需要与特定的Spring框架接口绑定,使得框架解耦。

后置处理器InitDestroyAnnotationBeanPostProcessor负责对标注了@PostConstruct、@PreDestroy的Bean进行处理。

ApplicationContext

高级容器,在BeanFactory的基础上提供更多高级功能。其与BeanFactory的区别在于:

  • bean的生成方式;
  • 扩展了BeanFactory的功能,提供了更多企业级功能的支持。
  • ApplicationContext采用的非懒加载方式。它会在启动阶段完成所有的初始化,并不会等到getBean()才执行
    • 所以,相对于BeanFactory来 说,ApplicationContext要求更多的系统资源,同时,因为在启动时就完成所有初始化,容 器启动时间较之BeanFactory也会长一些。在那些系统资源充足,并且要求更多功能的场景中, ApplicationContext类型的容器是比较合适的选择。

了解ApplicationContext当中的Bean生命周期:

1566526661839

其与BeanFactory类似,不同点有:

  • 如果Bean实现了org.springframework.context.ApplicationContext.Aware接口,则会增加应该调用该接口方法setApplicationContext()的步骤。
  • ApplicationContexthi利用Java反射自动识别出配置文件中定义的BeanPostProcessor、InstantiationAwareBeanPostProcessor和BeanFactoryPostProcessor,并自动将它们注册到应用上下文。而BeanFactory需要手动调用注册。

refresh()

  • registerBeanPostProcessors(beanFactory)。注册BeanPostProcessor。
  • finishBeanFactoryInitialization(beanFactory)。注册余下的Singletions Bean。

ApplicationContext初始化在refresh()方法中,并且ApplicationContext建立起来以后,其实我们是可以通过调用refresh()这个方法重建的,这样会将原来的ApplicationContext销毁,然后再重新执行一次初始化操作。

AbstractApplicationContext是ApplicationContext的抽象实现类,该抽象类的refresh()定义了Spring容器在加载配置文件后的各项处理过程,这些处理过程清晰地刻画了Spring容器启动时所执行的各项操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//初始化BeanFactory
ConfigurableListtableBeanFactory beanFactory = obtainFreshBeanFactory();

//调用工厂后处理器
invokeBeanFactoryPostProcessors();

//注册Bean后处理器
registerBeanPostProcessors();

//初始化消息源
initMessageSource();

//初始化应用上下文事件广播器
initApplicationEventMulticaster();

//初始化其他特殊的Bean,由具体子类实现
onRefresh();

//注册事件监听器
registerListeners();

//初始化所有单实例的Bean,使用懒加载模式的Bean除外
finishBeanFactoryInitialization(beanFactory);

//完成刷新并发布容器刷新事件
finishRefresh();
  • 初始化BeanFactory。根据配置文件实例化BeanFactory,在obtainFreshBeanFactory()方法中首先调用refreshBeanFactory()方法刷新BeanFactory,然后调用getBeanFactory()获取BeanFactory,在该步骤中Spring将配置文件的信息装入容器的Bean定义注册表(BeanDefinitionRegistry)中,但此时Bean还未初始化。
  • 调用工厂后处理器。根据反射机制从BeanDefinitionRegistry中找出所有实现了BeanFactoryPostProcessor接口的Bean,调用其postProcessBeanFactory()方法。
  • 注册Bean后处理器。根据反射机制从BeanDefinitionRegistry中找出所有实现了BeanPostProcessor接口的Bean,并将它们注册到容器Bean后处理器的注册表中。
  • 初始化消息源。初始化容器的国际化消息资源。
  • 初始化应用上下文事件广播器。

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 准备工作,记录下容器的启动时间、标记“已启动”状态、检验配置文件格式
prepareRefresh();
// ClassPathXmlApplicationContext 会在这里解析 xml 配置;AnnotationConfigApplicationContext 的解析发在初始化,这里只是简单的获取
// 这里的解析是指把配置信息都提取出来了,保存在了一个 Map<String, BeanDefinition> 中
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 设置 BeanFactory 的类加载器,添加几个BeanPostProcessor,手动注册几个特殊的 bean 等
prepareBeanFactory(beanFactory);
try {
// BeanFactory准备工作完成后进行的后置处理工作,子类可以自定义实现,Spring Boot中是个空方法
postProcessBeanFactory(beanFactory);
//=======以上是 BeanFactory 的预准备工作=======
// 调用BeanFactoryPostProcessor各个实现类的postProcessBeanFactory(factory)方法
invokeBeanFactoryPostProcessors(beanFactory);
// 注册和创建BeanPostProcessor的实现类(注意和之前的BeanFactoryPostProcessor的区别)
registerBeanPostProcessors(beanFactory);
// 初始化MessageSource组件(做国际化功能;消息绑定,消息解析)
initMessageSource();
// 初始化当前ApplicationContext的事件广播器
initApplicationEventMulticaster();
// 具体的子类可以在这里初始化一些特殊的Bean(在初始化singleton beans之前),Spring Boot 中默认没有定义
onRefresh();
// 注册事件监听器,监听器需要实现ApplicationListener接口
registerListeners();
// 初始化所有的singleton beans(lazy-init 的除外)
finishBeanFactoryInitialization(beanFactory);
// 容器刷新完成操作
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
destroyBeans();
cancelRefresh(ex);
throw ex;
}
finally {
resetCommonCaches();
}
}
}

prepareRefresh()

刷新前的准备工作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
protected void prepareRefresh() {
// 记录启动时间,
// 将 active 属性设置为 true,closed 属性设置为 false,它们都是 AtomicBoolean 类型
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);

// Spring Boot 中是个空方法
initPropertySources();

// 校验配置属性的合法性
getEnvironment().validateRequiredProperties();

// 记录早期的事件
this.earlyApplicationEvents = new LinkedHashSet<>();
}

obtainFreshBeanFactory()

在ApplicationContext当中持有了一个BeanFactory,这步就是获取ApplicationContext中的 BeanFactory。在AnnotationConfigApplicationContext中其已经创建好了,直接返回即可。

1
2
3
4
5
6
7
8
9
10
11
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
// 通过 cas 设置刷新状态
if (!this.refreshed.compareAndSet(false, true)) {
throw new IllegalStateException(
"GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
}
// 设置序列号
this.beanFactory.setSerializationId(getId());
// 返回已创建的 BeanFactory
return this.beanFactory;
}

prepareBeanFactory()

准备Bean容器,BeanFactory获取之后并不能马上使用,还要在BeanFactory中做一些准备工作,包括类加载器、表达式解析器的设置,几个特殊的BeanPostProcessor的添加等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 设置BeanFactory的类加载器,这里设置为当前ApplicationContext的类加载器
beanFactory.setBeanClassLoader(getClassLoader());
// 设置表达式解析器
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

// 添加Aware后置处理器,实现了Aware接口的beans在初始化的时候,这个processor负责回调
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));

/**
* 下面几行的意思是,如果某个bean依赖于以下几个接口的实现类,在自动装配的时候忽略它们,Spring会通过其他方式来处理这些依赖
*/
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

/**
* 下面几行是为了解决特殊的依赖,如果有bean依赖了以下几个(可以发现都是跟容器相关的接口),会注入这边相应的值,
* 这是因为Spring容器里面不保存容器本身,所以容器相关的依赖要到resolvableDependencies里面找。上文有提到过,
* ApplicationContext继承了ResourceLoader、ApplicationEventPublisher、MessageSource,所以对于这几个依赖,
* 可以赋值为this,注意this是一个ApplicationContext。
* 那这里怎么没看到为MessageSource赋值呢?那是因为MessageSource被注册成为了一个普通的bean。
*/
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);


/**
* 这也是个BeanPostProcessor,在bean实例化后,如果是ApplicationListener的子类,那么将其添加到listener列表中,
* 可以理解成:注册监听器。
*/
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}


/**
* 从下面几行代码我们可以知道,Spring往往很"智能"就是因为它会帮我们默认注册一些有用的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());
}
}

调用BeanFactory后置处理器

调用BeanFactoryPostProcessor的postProcessBeanFactory(beanFactory)方法,它允许在beanFactory准备完成之后对beanFactory进行一些修改,比如在bean初始化之前对beanFactory中的 beanDefinition进行修改。

注册各类Bean后置处理器

也是一个名字就体现功能的方法,把各种BeanPostProcessor注册到BeanFactory中(需要注意的是这里的注册会直接调用getBean()创建对象),BeanPostProcessor允许在bean初始化前后插手对bean的初始化过程。

初始化事件分派器

Event会有单独的篇幅详解,这里就不展开了。

初始化所有非懒加载singleton beans

这是容器刷新中最重要的方法。Spring 需要在这个阶段完成所有的 singleton beans 的实例化。这一步骤非常重要而且过程非常长,下一篇中我们来专门分析这个方法。

finishRefresh()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
protected void finishRefresh() {
clearResourceCaches();

// 创建Lifecycle处理器
initLifecycleProcessor();

// 调用LifecycleProcessor的onRefresh()方法,默认是调用所有Lifecycle的start()方法
getLifecycleProcessor().onRefresh();

// 发布容器刷新完成事件
publishEvent(new ContextRefreshedEvent(this));

LiveBeansView.registerApplicationContext(this);
}

注册BeanPostProcessor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
//注册BeanPostProcessor
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
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)) {
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);
}
}

// First, register the BeanPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

// Next, register the BeanPostProcessors that implement Ordered.
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
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);

// Now, register all regular BeanPostProcessors.
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

// 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).
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

通过beanFactory.getBeanNamesForType()来获取所有BeanPostProcessor。

BeanPostProcessor按优先级分为PriorityOrdered,Ordered和其他的,对他们分别进行操作。

  • 先beanFactory.getBean进性实例化,
  • 再使用sortPostProcessors()进行排序,
  • 最后registerBeanPostProcessors()进行注册。

注册/getBean

  • 先getSingleton()从缓存中获取Bean,如果没有则创建。
  • 创建过程先检查有无循环依赖,有则抛出异常。
  • 实例化bean前先实例化所依赖的对象。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

final String beanName = transformedBeanName(name);
Object bean;
//缓存
// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}

else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
//判断循环引用,抛异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}

// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
// this.beanDefinitionMap.containsKey(beanName); 就是判断有没有BeanDefinition
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}

if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}

try {
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);

// Guarantee initialization of beans that the current bean depends on.
// 获取bean的依赖,实例化bean前先实例化依赖。
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
try {
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
//创建实例
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}

else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}

else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
}
}
}

// Check if required type matches the type of the actual bean instance.
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
}
return (T) bean;
}

createBean()

resolveBeforeInstantiation()doCreateBean()之前调用,使用InstantiationAwareBeanPostProcessor,在Bean被创建之前处理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;

// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}

// Prepare method overrides.
try {
mbdToUse.prepareMethodOverrides();
}
...

try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
// 处理InstantiationAwareBeanPostProcessor
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
...

try {
//创建对象
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
...
}

resolveBeforeInstantiation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
// 调用InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}

doCreateBean() 创建bean

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {

// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 创建实例
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}

// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
mbd.postProcessed = true;
}
}

// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}

// Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}


if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException
}
}
}

// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}


return exposedObject;
}

createBeanInstance创建实例

populateBean设置Bean属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
return;
}
}

// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
boolean continueWithPropertyPopulation = true;

if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//#### postProcessAfterInstantiation ####
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}

if (!continueWithPropertyPopulation) {
return;
}

PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

// Add property values based on autowire by name if applicable.
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}

// Add property values based on autowire by type if applicable.
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}

pvs = newPvs;
}

boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);

if (hasInstAwareBpps || needsDepCheck) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}

if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}

initializeBean初始化方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
//处理BeanNameAware、BeanClassLoaderAware、BeanFactoryAware
invokeAwareMethods(beanName, bean);
}

Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//获取所有BeanPostProcessor,挨个执行postProcessBeforeInitialization方法
//如果有一个返回null,则不继续执行余下的BeanPostProcessor
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}

try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

return wrappedBean;
}

BeanPostProcessor

是什么

BeanPostProcessor:有两个方法postProcessBeforeInitialization()方法和postProcessAfterInitialization()

概述

这个接口的作用在于对于新构造的实例可以做一些自定义的修改。比如如何构造、属性值的修改、构造器的选择等等。

只要我们实现了这个接口,便可以对构造的bean进行自定义的修改。接口定义:

1
2
3
4
5
6
public interface BeanPostProcessor {
// 是指bean在初始化(init,非构造器)之前需要调用的方法。
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
// 是指bean在初始化之(init,非构造器)后需要调用的方法。
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
  • postProcessBeforeInitialization和postProcessAfterInitialization方法被调用的时候。这个时候bean已经被实例化,并且所有该注入的属性都已经被注入,是一个完整的bean。
  • 这2个方法的返回值可以是原先生成的实例bean,或者使用wrapper包装这个实例。

应用

适用性

  • 在bean初始化的时候,也就是Spring激活bean的init-method方法的时候调用。
    • 在之前会调用BeanPostProcessor的postProcessBeforeInitialization方法
    • 在之后会调用postProcessAfterInitialization方法。

应用场景

  • AOP。
  • 日常可以拓展该接口对bean初始化进行定制化处理。

InstantiationAwareBeanPostProcessor

是什么

InstantiationAwareBeanPostProcessor代表了Spring的另外一段生命周期:实例化。先区别一下Spring Bean的实例化和初始化两个阶段的主要作用:

  • 实例化:实例化的过程是一个创建Bean的过程,即调用Bean的构造函数,单例的Bean放入单例池中。
  • 初始化:初始化的过程是一个赋值的过程,即调用Bean的setter,设置Bean的属性。

InstantiationAwareBeanPostProcessor接口继承BeanPostProcessor接口,它内部提供了3个方法,再加上BeanPostProcessor接口内部的2个方法,所以实现这个接口需要实现5个方法。

应用

适用性

  • 主要作用在于目标对象的实例化过程中需要处理的事情,包括实例化对象的前后过程以及实例的属性设置
    • 用于替换bean默认创建方式,例如aop通过拓展接口生成代理对应,主要用于基础框架层面。
  • 在Bean实例化过程(生成实例对象)前后调用。
    • postProcessBeforeInstantiation。在目标对象被实例化之前调用的方法,可以返回目标实例的一个代理用来代替目标实例。
      • 典型的例如aop返回proxy对象。
    • postProcessAfterInstantiation。在目标对象被实例化之后并且在属性值被populate之前调用。
  • 初始化的过程调用。
    • 在初始化(setter注入,init方法)的过程中的setter注入这一步之前调用。涉及这两个方法 postProcessAfterInstantiation返回值boolean,postProcessPropertyValues()。

应用场景

实现

继承自BeanPostProcessor接口。多出了3个方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// postProcessBeforeInstantiation方法的作用在目标对象被实例化之前调用的方法,可以返回目标实例的一个代理用来代替目标实例
// beanClass参数表示目标对象的类型,beanName是目标实例在Spring容器中的name
// 返回值类型是Object,如果返回的是非null对象,接下来除了postProcessAfterInitialization方法会被执行以外,其它bean构造的那些方法都不再执行。否则那些过程以及postProcessAfterInitialization方法都会执行
Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException;

// postProcessAfterInstantiation方法的作用在目标对象被实例化之后并且在属性值被populate之前调用
// bean参数是目标实例(这个时候目标对象已经被实例化但是该实例的属性还没有被设置),beanName是目标实例在Spring容器中的name
// 返回值是boolean类型,如果返回true,目标实例内部的返回值会被populate,否则populate这个过程会被忽视
boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException;

// postProcessPropertyValues方法的作用在属性中被设置到目标实例之前调用,可以修改属性的设置
// pvs参数表示参数属性值(从BeanDefinition中获取),pds代表参数的描述信息(比如参数名,类型等描述信息),bean参数是目标实例,beanName是目标实例在Spring容器中的name
// 返回值是PropertyValues,可以使用一个全新的PropertyValues代替原先的PropertyValues用来覆盖属性设置或者直接在参数pvs上修改。如果返回值是null,那么会忽略属性设置这个过程(所有属性不论使用什么注解,最后都是null)
PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)
throws BeansException;
  • postProcessBeforeInstantiation。
    • 是最先执行的方法,它在目标对象实例化之前调用,该方法的返回值类型是Object,我们可以返回任何类型的值。由于这个时候目标对象还未实例化,所以这个返回值可以用来代替原本该生成的目标对象的实例(比如代理对象)。如果该方法的返回值代替原本该生成的目标对象,后续只有postProcessAfterInitialization方法会调用,其它方法不再调用;否则按照正常的流程走。
  • postProcessAfterInstantiation。
    • 方法在目标对象实例化之后调用,这个时候对象已经被实例化,但是该实例的属性还未被设置,都是null。如果该方法返回false,会忽略属性值的设置;如果返回true,会按照正常流程设置属性值。
  • postProcessPropertyValues
    • 方法对属性值进行修改(这个时候属性值还未被设置,但是我们可以修改原本该设置进去的属性值)。如果postProcessAfterInstantiation方法返回false,该方法不会被调用。可以在该方法内对属性值进行修改。
  • 父接口BeanPostProcessor的2个方法postProcessBeforeInitialization和postProcessAfterInitialization都是在目标对象被实例化之后,并且属性也被设置之后调用的。
  • Instantiation表示实例化,Initialization表示初始化。实例化的意思在对象还未生成,初始化的意思在对象已经生成。

postProcessBeforeInstantiation

1
2
3
4
5
6
7
8
9
10
11
12
13
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 执行所有InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}

postProcessAfterInitialization

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {

Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
// 执行所有beanProcessor.postProcessAfterInitialization
Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}

参考

  1. Spring内部的BeanPostProcessor接口总结
  2. 通过BeanPostProcessor理解Spring中Bean的生命周期及AOP原理