Spring学习(四)-Spring Bean

什么是Spring Bean

官方文档中的定义如下:

In Spring, the objects that form the backbone of your application and that are managed by the Spring IoC container are called beans. A bean is an object that is instantiated, assembled, and managed by a Spring IoC container.

翻译成中文如下:

在Spring中,构成应用程序主干并由Spring IoC容器管理的对象称为bean。 Bean是由Spring IoC容器实例化,组装和管理的对象

从之前关于BeanDefinition和BeanFactory的文章中可以知道,BeanDefinition就是用来描述一个Spring Bean,而BeanFactory就是用来管理Bean的。

Spring Bean实例化的方式

实例化的本质就是根据BeanDefinition来创建Bean实例。下面通过创建Person实例来说明。

@Getter
@Setter
@ToString
class Person{
    private String name;
    private Integer age;
    public Person() {
        this.name = "无参构造函数创建";
        this.age = 0;
    }
    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
}

构造方法

这是最常见也是用的最多的一种,示例如下:

<bean id="person1" class="com.buydeem.bean.Person"/>

上面的配置就是使用的无参构造方法创建实例,实际上它还可以在配置中指定构造方法参数和字段属性等。

静态工厂方法

该方法使用指定的静态方法来创建实例。通常需要定义一个静态方法如下:

public class BeanDemo {
    /**
     * 静态工厂
     * @return
     */
    public static Person createPerson(){
        return new Person("静态工厂创建",18);
    }
    /**
     * 指定参数的静态构造方法
     * @param name 名称
     * @return
     */
    public static Person createPerson2(String name){
        return new Person(name,19);
    }
}

配置文件如下:

<bean id="person3" class="com.buydeem.bean.BeanDemo" factory-method="createPerson"/>
<bean id="person4" class="com.buydeem.bean.BeanDemo" factory-method="createPerson2">
    <constructor-arg name="name" value="测试"/>
</bean>

配置中的class指定的静态方法所在类的名称,而factory-method指的是静态方法的名称。如果的静态工厂方法带有参数,我们可以通过constructor-arg指定静态方法的参数。

实例化工厂方法

该方式和静态工厂方法的方式差不多。该方式只需要先配置号factory实例,然后设置factory-bean和factory-method即可。

public class PersonFactory{
    public Person createPerson(){
        return new Person("实例化工厂创建",18);
    }
}

上面是实例化工厂的代码,下面就是配置文件

<bean id="personFactory" class="com.buydeem.bean.PersonFactory"/>
<bean id="person5" factory-bean="personFactory" factory-method="createPerson"/>

Spring Bean的生命周期

Spring Bean交给Spring管理换句话说就是Spring Bean的生命周期由Spring来控制。总体来说,Spring Bean的生命周期其实只有四个:实例化、属性赋值、初始化、销毁。在Spring中对应相关的英文为instantiation、populate、initialization和destruction。在Spring的关于生命周期的源代码中有很多方法和类都含有上面四个英文单词,了解上面的单词有利于源码的阅读。

上面只是总体来说分为4部分,但是复杂的地方就在于Spring提供了很多的扩展点,这些扩展点让Spring Bean的生命周期变的很复杂。

在Spring源码AbstractAutowireCapableBeanFactory中的doCreateBean方法可以看出Spring生命周期中的前三个,生命周期和方法分别对应如下:

createBeanInstance(beanName, mbd, args);//实例化
populateBean(beanName, mbd, instanceWrapper);//属性赋值
initializeBean(beanName, exposedObject, mbd);//初始化
1.png

实例化前后-InstantiationAwareBeanPostProcessor

该接口是BeanPostProcessor(可以暂时忽略)的子接口,它主要提供的是实例化之前和之后的回调,以及设置属性或者自动装配之前的回调。该接口主要提供了三个方法提供回调扩展。

postProcessBeforeInstantiation

default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
   return null;
}

该方法发生在实例化前,简单的说就对象还没有被创建出来。该方法如果返回值为非空,这将导致原本默认的实例化方法不会执行,而后续的postProcessAfterInstantiationpostProcessProperties将不会执行。从AbstractAutowireCapableBeanFactory中的createBean开始调试,可以查看到整个完整过程,下面是部分关键实现代码。

2.png

resolveBeforeInstantiation实现如下

3.png

applyBeanPostProcessorsBeforeInstantiation实现如下

4.png

postProcessAfterInstantiation

default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
   return true;
}

该方法在实例化之后,属性赋值之前被调用。如果该方法返回true,则代表应该进行属性赋值。如果返回false,则不会进行后续的属性赋值操作,同时将跳过postProcessProperties方法。具体实现可以看populateBean内部的实现。

5.png

postProcessProperties

default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
      throws BeansException {
   return null;
}

该方法在属性赋值之前调用。如果返回空或者是入参的pvs,则代表将会使用BeanDefinition中定义的值为属性赋值。我们可以修改返回的pvs,从而修改属性的赋值。在populateBean可以看到它的实现。

6.png

参考使用示例:

spring-life-cycle.xml定义如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean name="user" class="com.buydeem.lifecycle.User">
        <property name="userName" value="tom"/>
        <property name="age" value="18"/>
    </bean>
</beans>

示例代码:

public class LifecycleDemo {
    public static void main(String[] args) {
        //创建BeanFactory
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        //读取配置文件
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
        reader.loadBeanDefinitions("spring-life-cycle.xml");
        //注册 InstantiationAwareBeanPostProcessor
        beanFactory.addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessor());
        //获取Bean并打印
        User user = beanFactory.getBean("user", User.class);
        System.out.println(user);
    }
}

class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        System.out.println("MyInstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation()");
        return null;
    }
    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        System.out.println("MyInstantiationAwareBeanPostProcessor#postProcessAfterInstantiation()");
        return true;
    }
    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        System.out.println("MyInstantiationAwareBeanPostProcessor#postProcessProperties()");
        for (PropertyValue pv : pvs) {
            if (pv.getValue() instanceof TypedStringValue){
                TypedStringValue value = (TypedStringValue) pv.getValue();
                System.out.println(pv.getName() + " = " + value.getValue());
            }
        }
        MutablePropertyValues mvs = new MutablePropertyValues();
        mvs.add("userName", "update_name");
        mvs.add("age", 19);
        return mvs;
    }
}
class User {
    private String userName;
    private Integer age;
    public User() {
        System.out.println("User()");
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        System.out.println("setUserName()");
        this.userName = userName;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        System.out.println("setAge()");
        this.age = age;
    }
    @Override
    public String toString() {
        return "User{" +
                "userName='" + userName + '\'' +
                ", age=" + age +
                '}';
    }
}

打印结果如下:

MyInstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation()
User()
MyInstantiationAwareBeanPostProcessor#postProcessAfterInstantiation()
MyInstantiationAwareBeanPostProcessor#postProcessProperties()
userName = tom
age = 18
setUserName()
setAge()
User{userName='update_name', age=19}

初始化前后-BeanPostProcessor

该接口主要提供了初始化前后的扩展。前面分析的InstantiationAwareBeanPostProcessor作为该接口的子接口,也同样具备该功能。接口定义如下:

public interface BeanPostProcessor {
   default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
      return bean;
   }
   default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
      return bean;
   }
}

postProcessBeforeInitializationpostProcessAfterInitialization分别提供了初始化前后的回调入口。具体实现可以查看AbstractAutowireCapableBeanFactoryinitializeBean的实现。

7.png

applyBeanPostProcessorsBeforeInitialization实现如下:

8.png

applyBeanPostProcessorsAfterInitialization实现如下

9.png

从上面代码实现可以知道,分别在applyBeanPostProcessorsBeforeInitialization和applyBeanPostProcessorsAfterInitialization中对postProcessBeforeInitialization和postProcessAfterInitialization做了调用。需要注意的地方在于,BeanPostProcessor可以注册多个,且执行是有顺序的。如果接口的方法实现返回null,后续的BeanPostProcessor将会被跳过不再执行。

在之前的MyInstantiationAwareBeanPostProcessor中我们增加对postProcessBeforeInitialization和postProcessAfterInitialization的实现,修改代码如下:

class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        System.out.println("MyInstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation()");
        return null;
    }
    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        System.out.println("MyInstantiationAwareBeanPostProcessor#postProcessAfterInstantiation()");
        return true;
    }
    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        System.out.println("MyInstantiationAwareBeanPostProcessor#postProcessProperties()");
        for (PropertyValue pv : pvs) {
            if (pv.getValue() instanceof TypedStringValue){
                TypedStringValue value = (TypedStringValue) pv.getValue();
                System.out.println(pv.getName() + " = " + value.getValue());
            }
        }
        MutablePropertyValues mvs = new MutablePropertyValues();
        mvs.add("userName", "update_name");
        mvs.add("age", 19);
        return mvs;
    }
    //BeanPostProcessor中定义的接口
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("MyInstantiationAwareBeanPostProcessor#postProcessBeforeInitialization()");
        System.out.println(bean);
        if (bean instanceof User){
          ((User) bean).setAge(20);
        }
        return bean;
    }
    //BeanPostProcessor中定义的接口
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("MyInstantiationAwareBeanPostProcessor#postProcessAfterInitialization()");
        System.out.println(bean);
        if (bean instanceof User){
          ((User) bean).setAge(21);
            }
        return bean;
    }
}

最后的打印结果如下:

MyInstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation()
User()
MyInstantiationAwareBeanPostProcessor#postProcessAfterInstantiation()
MyInstantiationAwareBeanPostProcessor#postProcessProperties()
userName = tom
age = 18
setUserName()
setAge()
MyInstantiationAwareBeanPostProcessor#postProcessBeforeInitialization()
User{userName='update_name', age=19}
setAge()
MyInstantiationAwareBeanPostProcessor#postProcessAfterInitialization()
User{userName='update_name', age=20}
setAge()
User{userName='update_name', age=21}

在Spring中BeanPostProcessor有很多子集,这些子集提供了非常丰富的功能。例如在Spring中对JSR-250规范中@PostConstruct注解的实现,就是借助了BeanPostProcessor完成的。例如之前的示例,我们为User增加@PostConstruct标记的方法:

@PostConstruct
public void postConstruct(){
    System.out.println("User#postConstruct()");
}

向BeanFactory注册InitDestroyAnnotationBeanPostProcessor实例。nitDestroyAnnotationBeanPostProcessor postProcessor =newInitDestroyAnnotationBeanPostProcessor();

postProcessor.setInitAnnotationType(PostConstruct.class);
beanFactory.addBeanPostProcessor(postProcessor);

执行修改后的代码,打印结果如下:

MyInstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation()
User()
MyInstantiationAwareBeanPostProcessor#postProcessAfterInstantiation()
MyInstantiationAwareBeanPostProcessor#postProcessProperties()
userName = tom
age = 18
setUserName()
setAge()
MyInstantiationAwareBeanPostProcessor#postProcessBeforeInitialization()
User{userName='update_name', age=19}
setAge()
User#postConstruct()
MyInstantiationAwareBeanPostProcessor#postProcessAfterInitialization()
User{userName='update_name', age=20}
setAge()
User{userName='update_name', age=21}

最后输出的结果比之前多了User#postConstruct()。这个就是通过BeanPostProcessor实现的。在使用ApplicationContext时不需要手动注册,因为Spring已经帮你注册了CommonAnnotationBeanPostProcessor。

Aware接口回调

在Spring有很多Aware接口,当容器在创建实现了Aware相关的接口时,会自动的将某些实例注入的被创建的实例中。上面表述不清的话直接看示例。例如现在我定义一个Person实例,该实例需要持有BeanFactory实例。

public class LifecycleDemo2 {
    public static void main(String[] args) {
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(Person.class).getBeanDefinition();
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        beanFactory.registerBeanDefinition("person",beanDefinition);
        Person person = beanFactory.getBean(Person.class);
        System.out.println(person.getBeanFactory() == beanFactory);
    }
}
class Person implements BeanFactoryAware{
    private BeanFactory beanFactory;
    public BeanFactory getBeanFactory() {
        return beanFactory;
    }
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }
}

Person只需要实现BeanFactoryAware接口,然后容器会回调setBeanFactory方法,我们就能获取到BeanFactory实例了,而且最后打印的结果返回true也证实了容器给我们注入的BeanFactory就是我们自己手动创建出来的。具体Spring提供了哪些Aware请参考ApplicationContextAware and BeanNameAware官方相关文档。

BeanFactory中Aware实现

Spring是如何完成回调的呢?在前面的AbstractAutowireCapableBeanFactoryinitializeBean源码中标注了一个被调用的方法叫invokeAwareMethods。这个方法的实现如下所示:

10.png

整个逻辑很简单,就是判断是不是对应的Aware类型,如果是就调用对应的回调方法。但是这里只有三种,其他的都是在ApplicationContext环境中才有的。通过源码分析可以知道它是如何实现的。

ApplicationContext中Aware实现

查看AbstractApplicationContext、ApplicationContextAwareProcessor代码可以知道如何实现。

  1. 在使用ApplicationContext时都需要调用refresh()这个方法,这个方法会执行一个叫prepareBeanFactory(beanFactory)的方法。
  2. prepareBeanFactory中会创建一个ApplicationContextAwareProcessor实例,而这个ApplicationContextAwareProcessor就是一个BeanPostProcessor的实现,这个新创建的实例会被注册到BeanFactory上。
  3. 在postProcessBeforeInitialization方法中会调用invokeAwareInterfaces来实现Aware回调。

源码如下图所示:

AbstractApplicationContext#refresh方法

11.png

AbstractApplicationContext#prepareBeanFactory方法

12.png

ApplicationContextAwareProcessor内部实现

13.png

14.png

从上面的源码实现可以知道这BeanFactory中Aware和ApplicationContext中Aware的实现是不同的。ApplicationContext中Aware的实现是通过BeanPostProcessor实现的,这也说明BeanPostProcessor在Spring中作为扩展点的灵活和重要。

初始化-InitializingBean和init-method

在Spring中我们还可以通过实现InitializingBean或者指定init-method方法来就行初始化。还是在之前的示例中,主要做一下修改:

  1. User实现InitializingBean接口,并实现afterPropertiesSet()方法。
  2. User创建initMethod()方法,并在XML配置文件中指定init-method方法。

User类修改

class User implements InitializingBean {
    private String userName;
    private Integer age;
    public User() {
        System.out.println("User()");
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        System.out.println("setUserName()");
        this.userName = userName;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        System.out.println("setAge()");
        this.age = age;
    }
    @Override
    public String toString() {
        return "User{" +
                "userName='" + userName + '\'' +
                ", age=" + age +
                '}';
    }
    @PostConstruct
    public void postConstruct(){
        System.out.println("User#postConstruct()");
    }
    //修改处
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("afterPropertiesSet()");
    }
    //修改处
    public void initMethod(){
        System.out.println("initMethod()");
    }
}

spring-life-cycle.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean name="user" class="com.buydeem.lifecycle.User" init-method="initMethod">
        <property name="userName" value="tom"/>
        <property name="age" value="18"/>
    </bean>
</beans>

最后的打印结果如下:

MyInstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation()
User()
MyInstantiationAwareBeanPostProcessor#postProcessAfterInstantiation()
MyInstantiationAwareBeanPostProcessor#postProcessProperties()
userName = tom
age = 18
setUserName()
setAge()
MyInstantiationAwareBeanPostProcessor#postProcessBeforeInitialization()
User{userName='update_name', age=19}
setAge()
User#postConstruct()
afterPropertiesSet()
initMethod()
MyInstantiationAwareBeanPostProcessor#postProcessAfterInitialization()
User{userName='update_name', age=20}
setAge()
User{userName='update_name', age=21}

结果输出中可以看到新增afterPropertiesSet()initMethod()输出。还是查看之前initializeBean()方法的实现,在它内部会调用一个名叫invokeInitMethods的方法,该方法实现如下:

15.png

从上图可以看出,这个方法就是用来处理InitializingBean和init-method的。

销毁前置处理-DestructionAwareBeanPostProcessor

该接口同样也是BeanPostProcessor的子扩展,从这里可以看出,BeanPostProcessor确实就是Spring的扩展点,几乎所有的扩展点都是通过其扩展类来实现的。DestructionAwareBeanPostProcessor的定义如下:

public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor {
   //销毁前处理
   void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException;
   //确定给定的bean实例是否需要执行后置处理
   default boolean requiresDestruction(Object bean) {
      return true;
   }
}

简单的说就是requiresDestruction方法用来控制是否要经过postProcessBeforeDestruction方法处理,如果返回false,给定的Bean实例是不会执行postProcessBeforeDestruction方法中的逻辑的。
在前面的BeanPostProcessor中提到了InitDestroyAnnotationBeanPostProcessor这个类用来处理@PostConstruct注解,这个类同时还实现了DestructionAwareBeanPostProcessor接口用来处理@PreDestroy注解。

16.png

DisposableBean和destroy-method

在Spring中我们一般可以通过下面三种方式定义销毁回调:

  • @PreDestory注解
  • 实现DisposableBean
  • 定义destroy-method

前面已经说了@PreDestory是通过InitDestroyAnnotationBeanPostProcessor来实现的,后面的两种我们可以跟踪AbstractBeanFactory****#****destroyBean(String beanName, Object beanInstance)的实现来查看究竟如何实现。

protected void destroyBean(String beanName, Object bean, RootBeanDefinition mbd) {
   new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), getAccessControlContext()).destroy();
}

看到最后它就是通过创建一个DisposableBeanAdapter实例,然后调用其destroy方法执行销毁逻辑。而destroy的内部实现如下:

17.png

从上面可以看出

第一步会先执行DestructionAwareBeanPostProcessor#postProcessBeforeDestruction()中的逻辑****。

同样DisposableBeanAdapter也可以被注册多个,这些DisposableBeanAdapter被存储在DisposableBeanAdapter中的beanPostProcessors变量中,这个变量是一个List结构。同时在DisposableBeanAdapter中的并不会每个都执行,必须是requiresDestruction方法返回为true时才会被添加到beanPostProcessors这个List中,从DisposableBeanAdapter构造方法中可以得知。

this.beanPostProcessors = filterPostProcessors(postProcessors, bean);

上面就是DisposableBeanAdapter构造方法中为beanPostProcessors赋值的方法,该方法的实现如下:

18.png

从源码中可以看出,requiresDestruction返回为true时才会被添加到beanPostProcessors中。

第二步就是处理DisposableBean中destroy****()方法的回调。

第三步处理BeanDefinition中定义的destroyMethod。

生命周期总结

通过前面的分析,现在对于Spring Bean的生命周期不会太复杂了。总结来说就是四个主要流程,然后再这些流程中加入很多扩展。其实只要记住四个主要流程和扩展点的顺序,对Spring Bean的生命周期就好理解了。

19.jpg

这个图就是上面所有流程的总结。最后使用一个示例代码展示Spring中各个生命周期。

package com.buydeem.lifecycle;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
/**
 * todo 描述信息
 *
 * @author zengchao
 * @date 2021-02-03 15:37:37
 */
public class LifecycleDemo3 {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        context.register(Config.class);
        context.refresh();
        context.close();
    }
}
class Student implements InitializingBean, DisposableBean {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Student() {
        System.out.println("实例化Bean");
    }
    @PostConstruct
    public void postConstruct(){
        System.out.println("@PostConstruct");
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("InitializingBean#afterPropertiesSet()");
    }
    public void customInitMethod(){
        System.out.println("BeanDefinition中自定义的init-method");
    }

    @PreDestroy
    public void preDestroy(){
        System.out.println("@PreDestroy");
    }
    @Override
    public void destroy() throws Exception {
        System.out.println("DisposableBean#destroy()");
    }
    public void customDestroyMethod(){
        System.out.println("BeanDefinition中自定义的destroy-method");
    }
}
class CustomInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        System.out.println("InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation()");
        return null;
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        System.out.println("InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation()");
        return true;
    }
    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        System.out.println("InstantiationAwareBeanPostProcessor#postProcessProperties()");
        return null;
    }
}
class CustomBeanPostProcessor implements BeanPostProcessor{
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("BeanPostProcessor#postProcessBeforeInitialization()");
        return bean;
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("BeanPostProcessor#postProcessAfterInitialization()");
        return bean;
    }
}
class Config{
    @Bean(initMethod = "customInitMethod",destroyMethod = "customDestroyMethod")
    public Student student(){
        return new Student();
    }
    @Bean
    public CustomInstantiationAwareBeanPostProcessor customInstantiationAwareBeanPostProcessor(){
        return new CustomInstantiationAwareBeanPostProcessor();
    }
    @Bean
    public CustomBeanPostProcessor customBeanPostProcessor(){
        return new CustomBeanPostProcessor();
    }
}

打印结果如下:

InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation()
实例化Bean
InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation()
InstantiationAwareBeanPostProcessor#postProcessProperties()
BeanPostProcessor#postProcessBeforeInitialization()
@PostConstruct
InitializingBean#afterPropertiesSet()
BeanDefinition中自定义的init-method
BeanPostProcessor#postProcessAfterInitialization()
@PreDestroy
DisposableBean#destroy()
BeanDefinition中自定义的destroy-method
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,393评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,790评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,391评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,703评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,613评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,003评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,507评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,158评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,300评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,256评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,274评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,984评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,569评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,662评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,899评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,268评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,840评论 2 339

推荐阅读更多精彩内容