一、项目案例代码:
1.1.Student:

package com;
public class Student {

private String stuName, sex;

public Student() {
   System.out.println("1.【Student类的无参构造方法】: 创建学生对象的时候执行。 作用: 对对象进行初始化操作。");
}

public void setStuName(String stuName) {
   System.out.println("2.【setName()自定义方法】:  用set方式给属性赋值并在构造方法之后执行。 作用:注入学生的name属性");
   this.stuName = stuName;
}




// 自己编写的初始化方法
public void myInit() {
   System.out.println("6.【init-method属性设置的方法myInit()】:  一个bean实例化完后(全部属性设置完之后)执行。 " +
         "作用: 对对象进行初始化");
}


// 自己编写的销毁方法(和上边的方法相同)
public void myDestroy() {
   System.out.println("7.【destroy-method属性设置的方法myDestroy()】: 容器关闭的时候执行, " +
         "在销毁bean对象之前执行此方法进行一些操作(比如提示对象即将被销毁)");
}


public void setSex(String sex) {
   System.out.println("【set注入】注入学生的sex属性");
   this.sex = sex;
}

public String getSex() {
   return sex;
}



public String getStuName() {
   return stuName;
}



public String toString() {
   String msString = 
        String.format("com.StudentBean{ name=%s,sex=%s }", stuName,  sex);
   return msString;
}

}

1.2.applicationContext.xml:

<!--  bean标签: 用来配置Student类  (id相当于对象的表示) -->
<!--  可以通过id获取此配置生成的java对象 -->
<bean id="s1" class="com.Student" scope="singleton" init-method="myInit" 
      destroy-method="myDestroy">
    <property name="stuName" value="yz"/>
</bean>

1.3.Test.java

public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");

Student s1=ac.getBean(Student.class);

((ClassPathXmlApplicationContext)ac).registerShutdownHook();

}

二、运行结果:
创建bean对象后会调用myInit方法对对象进行初始化。

调用ClassPathXmlApplicationContext对象的registerShutdownHook()方法。

三、重构Student,实现接口:
3.1.重构Student,让其实现三个接口:

让Student类实现生命周期接口BeanNameAware,BeanFactoryAware,InitializingBean并实现对应的方法

public class Student implements BeanNameAware,BeanFactoryAware,InitializingBean{}

//BeanNameAware的setBeanName()方法:如果某个Bean实现了BeanNameAware接口,那么Spring将会将Bean实例的ID传递给setBeanName()方法,
// 在Bean类中新增一个beanName字段,并实现setBeanName()方法。
public void setBeanName(String beanId) {
this.beanName = beanId;
System.out.println("3.【BeanNameAware接口的, setBeanName()方法】: set方法执行完毕之后再执行。 作用:为bean对象设置id值," +
" Bean的id为:" + this.beanName);

}

//BeanFactoryAware的setBeanFactory方法。 beanFactory用于表示spring容器
// (可以理解对象工厂, 所有对象由beanFactory创建且由beanFactory保存)
//在此方法中可以用beanFactory获取其他bean对象来调用(但是spring不推荐,推荐用DI注入的方式)
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
System.out.println("4.【BeanFactoryAware接口的, setBeanFactory()方法】: bean的id设置完后执行。 " +
"作用:可以得到beanFactory对象的引用:"+beanFactory);
//比如:bean对象通过spring容器发布事件
}

//对象的属性设置完毕后,Spring容器会调用InitializingBean接口的afterPropertiesSet方法来对对象一些初始化操作
// (若不需要就不用实现InitializingBean接口)。
public void afterPropertiesSet() throws Exception {
System.out.println("5.【InitializingBean接口的, afterPropertiesSet()方法】 :一个bean实例化完后(全部属性设置完之后)执行。 " +
"作用:来完成一些初始化操作。(和init-method属性属性设置的方法一样)");
}

3.2.运行结果:

  1. 实例化Bean对象,这个时候Bean的对象是非常低级的,基本不能够被我们使用,因为连最基本的属性都没有设置,可以理解为连Autowired注解都是没有解析的; 我的理解:创建对象并调用构造方法

  2. 填充属性,当做完这一步,Bean对象基本是完整的了,可以理解为Autowired注解已经解析完毕,依赖注入完成了;  我的理解: 调用set方法已经赋值完毕

  3. 如果Bean实现了BeanNameAware接口,则调用setBeanName方法, 为bean对象设置id (beanName就是beanId);

  4. 如果Bean实现了BeanClassLoaderAware接口,则调用setBeanClassLoader方法;

  5. 如果Bean实现了BeanFactoryAware接口,则调用setBeanFactory方法;用于将Spring容器的引用(beanFactory的引用)传递给bean对象,在此方法中可以通过beanFactory对象来获取Spring容器中的其他Bean对象。(注:BeanClassLoaderAware在案例中没列出,实际BeanClassLoaderAware先执行BeanPostProcessor后执行 );

5.如果Bean实现了InitializingBean接口,调用afterPropertiesSet方法; 一个bean实例化完后(全部属性设置完之后)执行。 作用:来完成一些初始化操作。(和init-method属性属性设置的方法一样)

6.如果Bean定义了init-method方法,则调用Bean的init-method方法。 用于对对象进行初始化;

7.如果应用的上下文被销毁了,并且Bean实现了DisposableBean接口,则调用destroy方法,如果Bean定义了destory-method声明了销毁方法也会被调用(两个作用相同)。

四、BeanPostProcessor接口的实现:
4.1.MyBeanPostProcessor实现BeanPostProcessor接口

package com;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
//BeanPostProcessor的作用域是容器级: 用于对bean对象进行增强(初始化之前和初始化之后)
public class MyBeanPostProcessor implements BeanPostProcessor {

public MyBeanPostProcessor() {
	//System.out.println("【BeanPostProcessor接口】调用BeanPostProcessor的构造方法");
}

/**执行时机: bean对象创建了给属性赋值了,但对应的init方法还未执行。
 *  作 用 :  给bean对象添加新功能,进行增强(比如替换init方法<就不用写init方法了>)。*/
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
	System.out.println("MyBeanPostProcessor接口:【BeanPostProcessor接口的,postProcessBeforeInitialization方法】init之前执行,作用:对id属性值为 " + beanName + "的对象进行更改(增强)");
	return bean;
}

/**执行时机: bean对象创建了给属性赋值了,对应的init方法已经执行完毕。
 *  作 用 :  给bean对象添加新功能,进行增强(比如修改bean对象的属性值)。*/
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
	System.out.println("MyBeanPostProcessor接口: 【BeanPostProcessor接口的,postProcessAfterInitialization方法】,init之后执行,作用:对id属性值为 " + beanName + "的对象进行更改(增强)");
	return bean;
}

}

4.2.运行结果(其他代码不变):

如果在项目中创建MyBeanPostProcessor 类实现BeanPostProcessor接口,则生命周期方法的运行次序如下:

  1. 实例化Bean对象,这个时候Bean的对象是非常低级的,基本不能够被我们使用,因为连最基本的属性都没有设置,可以理解为连Autowired注解都是没有解析的; 我的理解:创建对象并调用构造方法
  2. 填充属性,当做完这一步,Bean对象基本是完整的了,可以理解为Autowired注解已经解析完毕,依赖注入完成了; 我的理解: 调用set方法已经赋值完毕
  3. 如果Bean实现了BeanNameAware接口,则调用setBeanName方法, 为bean对象设置id (beanName就是beanId);
  4. 如果Bean实现了BeanClassLoaderAware接口,则调用setBeanClassLoader方法;
  5. 如果Bean实现了BeanFactoryAware接口,则调用setBeanFactory方法;用于将Spring容器的引用(beanFactory的引用)传递给bean对象,在此方法中可以通过beanFactory对象来获取Spring容器中的其他Bean对象。(注:BeanClassLoaderAware在案例中没列出,实际BeanClassLoaderAware先执行BeanPostProcessor后执行 );

5.调用BeanPostProcessor接口的postProcessBeforeInitialization方法 。init之前执行,作用:对bean对象进行更改(增强)

  1. 如果Bean实现了InitializingBean接口,调用afterPropertiesSet方法;

  2. 如果Bean定义了init-method方法,则调用Bean的init-method方法。用于对对象进行初始化;

  3. 调用BeanPostProcessor的postProcessAfterInitialization方法:当进行到这一步,Bean已经被准备就绪了,一直停留在应用的上下文中,直到被销毁;

9.如果应用的上下文被销毁了,如果Bean实现了DisposableBean接口,则调用destroy方法,如果Bean定义了destory-method声明了销毁方法也会被调用。

五、InstantiationAwareBeanPostProcessor的实现:
5.1.MyInstantiationAwareBeanPostProcessor类实现接口

注: 这里根据课本采用的是InstantiationAwareBeanPostProcessor接口的实现类InstantiationAwareBeanPostProcessorAdapter(书上说为了编程方便)

package com;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;

//读音: Instantiation--印思旦欸深 。 单词意思: 实例化
//读音: Processor-----Pro 赛 思儿 。 单词意思: 处理器/加工器
public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
System.out.println("【InstantiationAwareBeanPostProcessor接口】 实例化Bean之前调用。");
return null;
}

public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
    System.out.println("【InstantiationAwareBeanPostProcessor接口】 实例化Bean之后调用。");
    return true;
}

}

5.2.applicationContext.xml

<bean id="miabpp" class="com.MyInstantiationAwareBeanPostProcessor"></bean>

5.3.运行结果:

【InstantiationAwareBeanPostProcessor接口】 实例化Bean之前(创建Bean对象之前)调用。

1.【Student类的无参构造方法】: 创建学生对象的时候执行。 作用: 对对象进行初始化操作。
【InstantiationAwareBeanPostProcessor接口】 实例化Bean之后(创建Bean对象之后)调用。
2.【setName()自定义方法】:  用set方式给属性赋值并在构造方法之后执行。 作用:注入学生的name属性
【set注入】注入学生的sex属性
3.【BeanNameAware接口的, setBeanName()方法】:  set方法执行完毕之后再执行。 作用:为bean对象设置id值, Bean的id为:s1
4.【BeanFactoryAware接口的, setBeanFactory()方法】:  bean的id设置完后执行。 作用:可以得到beanFactory对象的引用:org.springframework.beans.factory.support.DefaultListableBeanFactory@5ebec15: defining beans [beanPostProcessor,s1,beanFactoryPostProcessor,miabpp]; root of factory hierarchy
MyBeanPostProcessor接口:【BeanPostProcessor接口的,postProcessBeforeInitialization方法】init之前执行,作用:对id属性值为 s1的对象进行更改(增强)
5.【InitializingBean接口的, afterPropertiesSet()方法】 :一个bean实例化完后(全部属性设置完之后)执行。 作用:来完成一些初始化操作。(和init-method属性属性设置的方法一样)
6.【init-method属性设置的方法myInit()】:  一个bean实例化完后(全部属性设置完之后)执行。 作用: 对对象进行初始化
MyBeanPostProcessor接口: 【BeanPostProcessor接口的,postProcessAfterInitialization方法】,init之后执行,作用:对id属性值为 s1的对象进行更改(增强)
7.【destroy-method属性设置的方法myDestroy()】: 容器关闭的时候执行, 在销毁bean对象之前执行此方法进行一些操作(比如提示对象即将被销毁)

六、MyBeanFactoryPostProcessor接口的实现:
6.1.MyBeanFactoryPostProcessor实现BeanFactoryPostProcessor接口

package com;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionVisitor;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.util.StringValueResolver;

import java.util.Set;

/**BeanPostProcessor的作用域是容器级: 用于对bean对象进行增强(初始化之前和初始化之后)*/
//BeanFactoryPostProcessor,可以在spring的bean创建之前,修改bean的定义属性。
//也就是说,Spring允许BeanFactoryPostProcessor在容器实例化任何其它bean之前读取配置元数据,并可以根据需要进行修改
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

//private Set<String> strValues;

/*public MyBeanFactoryPostProcessor(Set<String> strValues) {
    this.strValues = strValues;
}*/

/**重写BeanFactoryPostProcessor的postProcessBeanFactory方法, 用于:对beanFactory进行增强。
 * (这里举例用beanFactory给bean的属性设置值)*/
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    System.out.println("0.【BeanFactoryPostProcessor接口的postProcessBeanFactory()】 " +
            "此方法在对象创建之前执行(bean工厂<beanFactory,也就是spring容器>创建之后),作用:对beanFactory进行增强。" +
            "(这里举例用beanFactory给bean的属性设置值)");
    BeanDefinition beanDefinition=beanFactory.getBeanDefinition("s1");
    beanDefinition.getPropertyValues().addPropertyValue("sex","男");//会调用setSex()方法


    /*String []  beanIds=beanFactory.getBeanDefinitionNames();//1.获取所有bean的id
    for (String beanId : beanIds ) {
        BeanDefinition bean=beanFactory.getBeanDefinition(beanId);//2.用beanFactory根据beanId获取bean对象

        // 创建了一个string类型的解析器(作用:如果strVal在applicationContext.xml中存在,就用***代替)
        StringValueResolver stringValueResolver=new StringValueResolver() {
            public String resolveStringValue(String strVal) {
                if(strValues.contains( strVal.toLowerCase())){
                    return "***";
                }else{
                    return strVal;
                }
            }
        };
        //使用上边的解析器创建bean对象访问器BeanDefinitionVisitor
        BeanDefinitionVisitor beanDefinitionVisitor=new BeanDefinitionVisitor(stringValueResolver);
        //3.用beanDefinitionVisitor的visitBeanDefinition方法访问bean对象(对bean对象进行增强,将对象的敏感字替换为***)
        beanDefinitionVisitor.visitBeanDefinition(bean);
    }*/


}

}

6.2.运行结果:

通过MyBeanFactoryPostProcessor 的postProcessBeanFactory()方法给bean对象的age属性赋值了 (并且最先执行)。

postProcessBeanFactory()方法 在bean对象在实例化之前被执行,而 BeanPostProcessor 的postProcessBeforeInitialization()方法和postProcessAfterInitialization()方法则是在实例化过程中使用(init之前和之后执行)。

实现MyBeanFactoryPostProcessor 接口,可以在 Spring 创建 bean 之前修改 bean 的定义属性。也就是说,Srping 允许 BeanFactoryPostProcessor 在容器实例化 bean 之前读取配置元数据,并可以根据需要进行修改。例如可以把 bean 的 Scope 从 singleton 改为 prototype ,也可以把 property 的值给修改掉。另外可以同时配置多个 BeanFactoryPostProcessor,并通过 order 属性来控制 BeanFactoryPostProcessor 的执行顺序 ( 在实现 BeanFactoryPostProcessor 时应该考虑实现 Ordered 接口 )。

BeanFactoryPostProcessor 是在 Spring 容器加载了定义 bean 的 XML 文件之后,在 bean 实例化之前执行的。接口方法的入参是 ConfigurrableListableBeanFactory 类型,使用该参数可以获取到相关的 bean 的定义信息。
                        
本段话的原文链接:https://blog.csdn.net/Herishwater/article/details/103864534

0.【BeanFactoryPostProcessor接口的postProcessBeanFactory()】 此方法在对象创建之前执行(bean工厂<beanFactory,也就是spring容器>创建之后),作用:对beanFactory进行增强。(这里举例用beanFactory给bean的age属性设置值)
【InstantiationAwareBeanPostProcessor接口】 实例化Bean之前(创建Bean对象之前)调用。
1.【Student类的无参构造方法】: 创建学生对象的时候执行。 作用: 对对象进行初始化操作。
【InstantiationAwareBeanPostProcessor接口】 实例化Bean之后(创建Bean对象之后)调用。
2.【setName()自定义方法】:  用set方式给属性赋值并在构造方法之后执行。 作用:注入学生的name属性
【set注入】注入学生的sex属性
3.【BeanNameAware接口的, setBeanName()方法】:  set方法执行完毕之后再执行。 作用:为bean对象设置id值, Bean的id为:s1
4.【BeanFactoryAware接口的, setBeanFactory()方法】:  bean的id设置完后执行。 作用:可以得到beanFactory对象的引用:org.springframework.beans.factory.support.DefaultListableBeanFactory@5ebec15: defining beans [beanPostProcessor,s1,beanFactoryPostProcessor,miabpp]; root of factory hierarchy
MyBeanPostProcessor接口:【BeanPostProcessor接口的,postProcessBeforeInitialization方法】init之前执行,作用:对id属性值为 s1的对象进行更改(增强)
5.【InitializingBean接口的, afterPropertiesSet()方法】 :一个bean实例化完后(全部属性设置完之后)执行。 作用:来完成一些初始化操作。(和init-method属性属性设置的方法一样)
6.【init-method属性设置的方法myInit()】:  一个bean实例化完后(全部属性设置完之后)执行。 作用: 对对象进行初始化
MyBeanPostProcessor接口: 【BeanPostProcessor接口的,postProcessAfterInitialization方法】,init之后执行,作用:对id属性值为 s1的对象进行更改(增强)
7.【destroy-method属性设置的方法myDestroy()】: 容器关闭的时候执行, 在销毁bean对象之前执行此方法进行一些操作(比如提示对象即将被销毁)