关于BeanFactoryPostProcessor、BeanPostProcessor、@ConfigurationProperties、@Bean的执行顺序问题
CustomPostProcessorBean
package com.beanFactoryPostProcessorDemo;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
@Service
@ConfigurationProperties(prefix="test.abc")
public class CustomPostProcessorBean implements InitializingBean{
private String username;
private String password;
private String hello;
private String fuck;
@Bean(name="beanBeanDemo",initMethod="initMethod")
public BeanDemo iDontKnow() {
System.out.println("当前类===="+this.getClass());
return new BeanDemo();
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getHello() {
return hello;
}
public void setHello(String hello) {
this.hello = hello;
}
public String getFuck() {
return fuck;
}
public void setFuck(String fuck) {
this.fuck = fuck;
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("所有的属性已经全部设置了 =========================================");
}
}
BeanFactoryPostProcessor
package com.beanFactoryPostProcessorDemo;
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Service;
@Service
public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor,Ordered{
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
BeanDefinition bd = beanFactory.getBeanDefinition("postProcessorBean");
MutablePropertyValues pv = bd.getPropertyValues();
if(pv.contains("username")){
pv.addPropertyValue("username", "赵四");
}
}
@Override
public int getOrder() {
return 0;
}
}
BeanPostProcessor
package com.beanFactoryPostProcessorDemo;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Service;
@Service
public class CustomBeanPostProcessor implements BeanPostProcessor{
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if(bean instanceof CustomPostProcessorBean){
System.out.println("PostProcessorBean Bean initialized---------------------postProcessBeforeInitialization---------");
CustomPostProcessorBean pb = (CustomPostProcessorBean)bean;
pb.setFuck("fuck two");
System.out.println("username:"+pb.getUsername());
}
if(bean instanceof BeanDemo) {
System.out.println("=============postProcessBeforeInitialization ===beanDemo");
BeanDemo demo = (BeanDemo) bean;
demo.setId("postProcessBeforeInitialization-set");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if(bean instanceof CustomPostProcessorBean){
System.out.println("PostProcessorBean Bean initializing=====================postProcessAfterInitialization========");
CustomPostProcessorBean pb = (CustomPostProcessorBean)bean;
System.out.println("username:"+pb.getUsername());
}
if(bean instanceof BeanDemo) {
System.out.println("=============postProcessAfterInitialization ===beanDemo");
BeanDemo demo = (BeanDemo) bean;
demo.setId("postProcessAfterInitialization-set");
}
return bean;
}
}
BeanDemo
package com.beanFactoryPostProcessorDemo;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix="bean.demo")
public class BeanDemo implements InitializingBean{
private String name;
private String id;
private String wangba;
private void initMethod() {
System.out.println("BeanDemo 的 initMethod ===================");
this.name = "initMethod - name";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getWangba() {
return wangba;
}
public void setWangba(String wangba) {
this.wangba = wangba;
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("beanDemo 已经初始化完成了!=========================");
}
}
ServerApplication
package org.spring.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import com.beanFactoryPostProcessorDemo.BeanDemo;
import com.beanFactoryPostProcessorDemo.PostProcessorBean;
/**
* Spring Boot 应用启动类
*
* Created by bysocket on 16/4/26.
*/
// Spring Boot 应用的标识
@SpringBootApplication
@ComponentScan(basePackages= {"com.beanFactoryPostProcessorDemo"})
public class ServerApplication {
public static void main(String[] args) {
// 程序启动入口
// 启动嵌入式的 Tomcat 并初始化 Spring 环境及其各 Spring 组件
ConfigurableApplicationContext context
= SpringApplication.run(ServerApplication.class,args);
PostProcessorBean bean =(PostProcessorBean)context.getBean("postProcessorBean");
System.out.println("---------------testBeanFactoryPostProcessor----------------");
System.out.println("username:"+bean.getHello());
System.out.println("password:"+bean.getFuck());
BeanDemo beanDemo =(BeanDemo)context.getBean("beanBeanDemo");
System.out.println("beanDemo name:"+beanDemo.getName());
System.out.println("beanDemo wangba:"+beanDemo.getWangba());
}
}
application.properties
test.abc.hello=hello
test.abc.fuck=fuck
test.abc.go=go
bean.demo.wangba=wugui
总结:
BeanFactoryPostProcessor
|- postProcessBeanFactory
BeanPostProcessor
|- postProcessBeforeInitialization
|- postProcessAfterInitialization
InitializingBean
|- afterPropertiesSet
@ConfigurationProperties
|-@ConfigurationProperties(prefix="test.abc")
@Bean
|-@Bean(name="beanBeanDemo",initMethod="initMethod")
**当目标类PostProcessorBean被创建的时候,执行的步骤如下:**
1: 首先spring读取扫描的结果,这个时候还没有初始化类。
2: 执行 BeanFactoryPostProcessor -> postProcessBeanFactory
3: 执行 BeanPostProcessor -> postProcessBeforeInitialization
between 3 and 4: -|- 1: @ConfigurationProperties 会在这个时间点执行
执行 PostProcessorBean<? implements InitializingBean> -> afterPropertiesSet
|- 2: initMethod
4: 执行 BeanPostProcessor -> postProcessAfterInitialization
5: 执行 @Bean, 如果这里面有@Bean注解的话 --> 3 --> between 3 and 4 --> 4。
再补充两句:
测试发现@Bean创建的时候并没有执行
2: 执行 BeanFactoryPostProcessor -> postProcessBeanFactory