BeanFactoryPostProcessor和BeanPostProcessor区别

Spring的BeanFactoryPostProcessor和BeanPostProcessor区别

目录

Spring的BeanFactoryPostProcessor和BeanPostProcessor区别

BeanFactoryPostProcessor

自定义TestBeanFactoryPostProcessor 实现BeanFactoryPostProcessor扩展

appcontext.xml的配置

测试

运行结果

BeanPostProcessor

自定义InitBeanPostProcessor类实现BeanPostProcessor接口

 执行结果

总结



BeanFactoryPostProcessor:BeanFactory后置处理器,是对BeanDefinition对象进行修改(BeanDefinition:存储bean标签的信息,用来生成bean实例)
BeanPostProcessor:Bean后置处理器,是对生成的Bean对象进行修改

Spring IoC容器允许BeanFactoryPostProcessor在容器实例化任何bean之前读取bean的定义(配置元数据),并可以修改它。同时可以定义BeanFactoryPostProcessor,通过设置’order’属性来确定各个BeanFactoryPostProcessor执行顺序。
所有如果我们想要对BeanDefinition对象进行修改可以通过自定义一个Java类实现BeanFactoryPostProcessor接口并且重写接口中的postProcessBeanFactory方法

BeanFactoryPostProcessor

public interface BeanFactoryPostProcessor {

	/**
	 * Modify the application context's internal bean factory after its standard
	 * initialization. All bean definitions will have been loaded, but no beans
	 * will have been instantiated yet. This allows for overriding or adding
	 * properties even to eager-initializing beans.
	 * @param beanFactory the bean factory used by the application context
	 * @throws org.springframework.beans.BeansException in case of errors
	 */
	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}

自定义TestBeanFactoryPostProcessor 实现BeanFactoryPostProcessor扩展

package springCloud.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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;

/**
 * @author LWH
 * @version 1.0.0
 * @description: TODO
 * @date 2021/2/26 10:08
 */
public class TestBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    private static Logger logger = LoggerFactory.getLogger(TestBeanFactoryPostProcessor.class);
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        //System.out.println("第一步:BeanFactoryPostProcessor=====>postProcessBeanFactory 工厂后处理器, ApplicationContext容器初始化中refresh()中调用");

        String[] names = configurableListableBeanFactory.getBeanDefinitionNames();
        for (String name : names) {
            if("user".equals(name)){
                BeanDefinition beanDefinition = configurableListableBeanFactory.getBeanDefinition(name);
                //获取user中注入的属性信息
                MutablePropertyValues propertyValues = beanDefinition.getPropertyValues();
                System.out.println("propertyValues"+propertyValues);
                // MutablePropertyValues如果设置了相关属性,可以修改,如果没有设置则可以添加相关属性信息
                if(propertyValues.contains("name")){
                    propertyValues.addPropertyValue("name", "小明");
                }
                if(propertyValues.contains("age")){
                    propertyValues.addPropertyValue("age", "25");
                }
            }
        }
        System.out.println("BeanFactoryPostProcessor扩展修改BeanDefinition中user执行结束");
    }

}

appcontext.xml的配置




    
    
    
        
        
        
    
    
  
    

测试

 public static void main(String[] args) {
        ClassPathXmlApplicationContext context =
                new ClassPathXmlApplicationContext("appcontext.xml");
        User user = (User) context.getBean("user");
        System.out.println("创建bean完成=====" + user);
        context.close();
    }

运行结果

propertyValuesPropertyValues: length=3; bean property 'name'; bean property 'age'; bean property 'sex'
BeanFactoryPostProcessor扩展修改BeanDefinition中user执行结束
17:06:06.169 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor'
17:06:06.169 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalCommonAnnotationProcessor'
17:06:06.174 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'user'
第三步:-----构造方法,实例化User对象------
@PostConstruct======初始化回调方法
第十四步:创建bean完成=====User{name='小明', age='25', sex='男'}
17:06:06.217 [main] DEBUG org.springframework.context.support.ClassPathXmlApplicationContext - Closing org.springframework.context.support.ClassPathXmlApplicationContext@de0a01f, started on Fri Feb 26 17:06:05 GMT+08:00 2021
最后一步销毁:User bean

BeanPostProcessor

public interface BeanPostProcessor {
    /**
     * 在任何bean初始化回调之前(例如InitializingBean的afterPropertiesSet或自定义init-method)之前,
     */
    @Nullable
    default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    /**
     * 在任何bean初始化回调之后(例如InitializingBean的afterPropertiesSet或自定义init-method)之后,
     */
    @Nullable
    default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}

自定义InitBeanPostProcessor类实现BeanPostProcessor接口

package com.springCloud.config;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

import java.lang.reflect.Field;

/**
 * @author LWH
 * @version 1.0.0
 * @description: TODO〈〉
 * @date 2021/2/27 9:20 上午
 */
@Slf4j
public class InitBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object obj, String s) throws BeansException {
        if (s.equals("user")) {
            Field[] declaredFields = obj.getClass().getDeclaredFields();
            log.info("declaredFields {}", JSON.toJSONString(declaredFields));
            for (Field declaredField : declaredFields) {
                if ("name".equals(declaredField.getName())) {
                    try {
                        //修改对象的属性
                        declaredField.setAccessible(true);
                        declaredField.set(obj, "小黑");
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        System.out.println("第八步.BeanPostProcessor======>postProcessBeforeInitialization 注入属性完成准备实例化, bean = " + obj);
        return obj;
    }

    @Override
    public Object postProcessAfterInitialization(Object obj, String s) throws BeansException {
        System.out.println("第十二步.BeanPostProcessor======>postProcessAfterInitialization" + "=====在init-method之后调用=====" + "bean =" + obj);
        if (s.equals("user")) {
            Field[] declaredFields = obj.getClass().getDeclaredFields();
            log.info("declaredFields {}", JSON.toJSONString(declaredFields));
            for (Field declaredField : declaredFields) {
                if ("name".equals(declaredField.getName())) {
                    try {
                        //修改对象的属性
                        declaredField.setAccessible(true);
                        declaredField.set(obj, "小红");
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        return obj;
    }


}

 执行结果

从执行结果可以看出BeanPostProcessor中的postProcessBeforeInitialization方法和postProcessAfterInitialization方法是作用在bean的实例化、属性注入之后,在bean初始化的以前以后执行。我们在BeanFactoryPostProcessor中修改了我们在appcontext.xml中配置的user属性,在BeanPostProcessor中的postProcessBeforeInitialization方法和postProcessAfterInitialization又分别修改了user的name属性。

第一步:BeanFactoryPostProcessor=====>postProcessBeanFactory 工厂后处理器, ApplicationContext容器初始化中refresh()中调用
第二步:InstantiationAwareBeanPostProcessor======>postProcessBeforeInstantiation (该方法在实例化bean,调用构造方法前调用)com.springCloud.dto.User
num =1
实例化对象之前name =nullage =nullsex =null
第三步:-----构造方法,实例化User对象------
实例化对象之后name =nullage =nullsex =null
第四步:InstantiationAwareBeanPostProcessor======>postProcessAfterInstantiation实例化之后
第五步:InstantiationAwareBeanPostProcessor=====>postProcessProperties 注入bean的属性property=====属性对象PropertyValues: length=3; bean property 'name'; bean property 'age'; bean property 'sex'bean的名称user
第六步:setBeanName(实现BeanNameAware接口) 属性注入后调用
第七步:setBeanFactory(实现了BeanFactoryAware接口)
第八步.BeanPostProcessor======>postProcessBeforeInitialization 注入属性完成准备实例化, bean = User{name='小黑', age='25', sex='男'}
第九步:InstantiationAwareBeanPostProcessor====>postProcessBeforeInitialization 
@PostConstruct======初始化回调方法
第十步:afterPropertiesSet(实现InitializingBean接口) 在processBeforeInitialization之后调用,在init方法之前调用
第十一步:-------开始初始化init-method-----
第十二步.BeanPostProcessor======>postProcessAfterInitialization=====在init-method之后调用=====bean =User{name='小黑', age='25', sex='男'}
第十三步:InstantiationAwareBeanPostProcessor====>postProcessAfterInitialization
第十四步:创建bean完成=====User{name='小红', age='25', sex='男'}
最后一步销毁:User bean

总结

当然BeanFactoryPostProcessor接口和BeanPostProcessor接口还有很多扩展功能值得我们去钻研学习,今天小编就先展示到这里。
BeanFactoryPostProcessor:BeanFactory后置处理器,是对BeanDefinition对象进行修改(BeanDefinition:存储bean标签的信息,用来生成bean实例)
BeanPostProcessor:Bean后置处理器,作用在bean初始化的前后,是对生成的Bean对象进行修改
BeanPostProcessor的子类InstantiationAwareBeanPostProcessorBean实例化前后回调用。

 

 

你可能感兴趣的:(spring,bean,java)