美文网首页
Spring源码-PostProcessor

Spring源码-PostProcessor

作者: 一个煎饼 | 来源:发表于2021-06-22 11:01 被阅读0次

    基本定义

    PostProcessor

    官方定义为后置处理器(也叫增强器)。属于Spring中对的实例化、初始化过程中对BeanBeanDefinition进行修改(增强)。

    BeanPostProcessorBeanFactoryPostProcessor

    BeanPostProcessor用来对要自定义的Bean进行一系列的属性修改
    BeanFactoryPostProcessor 用来对BeanFactory的内容进行一系列的修改,在其中可以获取到BeanFactory中的Bean和BeanDefinition等对象信息

    BeanPostProcessor

    package org.springframework.beans.factory.config;
    
    import org.springframework.beans.BeansException;
    import org.springframework.lang.Nullable;
    
    public interface BeanPostProcessor {
    
        // Bean初始化 init-method之前执行
        @Nullable
        default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            return bean;
        }
    
        // Bean初始化 init-method之后执行
        @Nullable
        default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            return bean;
        }
    }
    
    

    BeanFactoryPostProcessor

    public interface BeanFactoryPostProcessor {
    
        // 工厂钩子,允许自定义修改应用程序上下文的 bean 定义,调整上下文底层 bean 工厂的 bean 属性值。此时Bean会被加载,但是并未实例化
        void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
    
    }
    

    spring-test模块中创建如图文件

    目录结构.png

    1、创建对象UserBean

    package org.springframework.demo;
    
    import java.util.logging.Logger;
    
    public class UserBean {
        Logger log = Logger.getAnonymousLogger();
    
        public UserBean() {
            log.info("UserBean 实例化");
        }
    
        private String userName;
        private String age;
    
        public String getAge() {
            return age;
        }
    
        public void setAge(String age) {
            this.age = age;
        }
    
        public String getUserName() {
            log.info("UserBean.getUserName:" + this.userName);
            return userName;
        }
    
        public void setUserName(String userName) {
            this.userName = userName;
        }
    
        public void init() {
            log.info("UserBean init");
        }
    
        @Override
        public String toString() {
            return "UserBean{" +
                    "userName='" + userName + '\'' +
                    ", age='" + age + '\'' +
                    '}';
        }
    }
    

    2、创建MyBeanPostProcessorMyBeanPostProcessor2实现BeanPostProcessorOrdered接口,这里两个实现类的优先级分别为01,用于模拟在存在多个BeanPostProcessor实现类的时候的执行顺序。

    package org.springframework.demo;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanPostProcessor;
    import org.springframework.core.Ordered;
    
    import java.util.logging.Logger;
    
    public class MyBeanPostProcessor implements BeanPostProcessor, Ordered {
        Logger log = Logger.getAnonymousLogger();
    
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            if (beanName.equals("userBean")){
                UserBean userBean = (UserBean) bean;
                userBean.setUserName("ZhangSan1");
                log.info("初始化 before--实例化的bean对象");
                log.info(userBean.toString());
            }
            return bean;
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            if (beanName.equals("userBean")){
                UserBean userBean = (UserBean) bean;
                userBean.setUserName("ZhangSan2");
                log.info("初始化 after--实例化的bean对象");
                log.info(userBean.toString());
            }
            return bean;
        }
    
        @Override
        public int getOrder() {
            return 0;
        }
    }
    
    
    package org.springframework.demo;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanPostProcessor;
    import org.springframework.core.Ordered;
    
    import java.util.logging.Logger;
    
    public class MyBeanPostProcessor2 implements BeanPostProcessor, Ordered {
        Logger log = Logger.getAnonymousLogger();
    
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            if (beanName.equals("userBean")){
                UserBean userBean = (UserBean) bean;
                userBean.setUserName("ZhangSan3");
                log.info("初始化 before--实例化的bean对象");
                log.info(userBean.toString());
            }
            return bean;
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            if (beanName.equals("userBean")){
                UserBean userBean = (UserBean) bean;
                userBean.setUserName("ZhangSan4");
                log.info("初始化 after--实例化的bean对象");
                log.info(userBean.toString());
            }
            return bean;
        }
    
        @Override
        public int getOrder() {
            return 1;
        }
    }
    
    

    3、创建MyBeanFactoryPostProcessor类实现BeanFactoryPostProcessor接口

    package org.springframework.demo;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanDefinition;
    import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
    import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
    
    import java.util.logging.Logger;
    
    public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    
        Logger log = Logger.getAnonymousLogger();
    
        @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
            BeanDefinition userBeanDefinition = beanFactory.getBeanDefinition("userBean");
            userBeanDefinition.isSingleton();
            log.info(userBeanDefinition.getFactoryBeanName());
            log.info(userBeanDefinition.getBeanClassName());
            log.info(userBeanDefinition.getDestroyMethodName());
            log.info(userBeanDefinition.getDescription());
        }
    }
    

    4、通过XML方式注册Bean,在Resource根目录创建application-context.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 http://www.springframework.org/schema/beans/spring-beans.xsd">
        <bean name="userBean" class="org.springframework.demo.UserBean" init-method="init"/>
        <bean name="myBeanFactoryPostProcessor" class="org.springframework.demo.MyBeanFactoryPostProcessor"/>
        <bean name="myBeanPostProcessor" class="org.springframework.demo.MyBeanPostProcessor"/>
        <bean name="myBeanPostProcessor2" class="org.springframework.demo.MyBeanPostProcessor2"/>
    </beans>
    

    5、编写测试类TestMain

    package org.springframework.demo;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import java.util.function.Supplier;
    import java.util.logging.Logger;
    
    public class TestMain {
    
        private static Logger log = Logger.getAnonymousLogger();
    
        public static void main(String[] args) {
    
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application-context.xml");
            UserBean bean = applicationContext.getBean(UserBean.class);
            log.info(bean.toString());
        }
    }
    

    Task :spring-test:TestMain.main()
    SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
    SLF4J: Defaulting to no-operation (NOP) logger implementation
    SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
    六月 22, 2021 10:00:20 上午 org.springframework.demo.MyBeanFactoryPostProcessor postProcessBeanFactory
    信息: null
    六月 22, 2021 10:00:20 上午 org.springframework.demo.MyBeanFactoryPostProcessor postProcessBeanFactory
    信息: org.springframework.demo.UserBean
    六月 22, 2021 10:00:20 上午 org.springframework.demo.MyBeanFactoryPostProcessor postProcessBeanFactory
    信息: null
    六月 22, 2021 10:00:20 上午 org.springframework.demo.MyBeanFactoryPostProcessor postProcessBeanFactory
    信息: null
    六月 22, 2021 10:00:20 上午 org.springframework.demo.UserBean <init>
    信息: UserBean 实例化
    六月 22, 2021 10:00:20 上午 org.springframework.demo.MyBeanPostProcessor postProcessBeforeInitialization
    信息: 初始化 before--实例化的bean对象
    六月 22, 2021 10:00:20 上午 org.springframework.demo.MyBeanPostProcessor postProcessBeforeInitialization
    信息: UserBean{userName='ZhangSan1', age='null'}
    六月 22, 2021 10:00:20 上午 org.springframework.demo.MyBeanPostProcessor2 postProcessBeforeInitialization
    信息: 初始化 before--实例化的bean对象
    六月 22, 2021 10:00:20 上午 org.springframework.demo.MyBeanPostProcessor2 postProcessBeforeInitialization
    信息: UserBean{userName='ZhangSan3', age='null'}
    六月 22, 2021 10:00:20 上午 org.springframework.demo.UserBean init
    信息: UserBean init
    六月 22, 2021 10:00:20 上午 org.springframework.demo.MyBeanPostProcessor postProcessAfterInitialization
    信息: 初始化 after--实例化的bean对象
    六月 22, 2021 10:00:20 上午 org.springframework.demo.MyBeanPostProcessor postProcessAfterInitialization
    信息: UserBean{userName='ZhangSan2', age='null'}
    六月 22, 2021 10:00:20 上午 org.springframework.demo.MyBeanPostProcessor2 postProcessAfterInitialization
    信息: 初始化 after--实例化的bean对象
    六月 22, 2021 10:00:20 上午 org.springframework.demo.MyBeanPostProcessor2 postProcessAfterInitialization
    信息: UserBean{userName='ZhangSan4', age='null'}
    六月 22, 2021 10:00:20 上午 org.springframework.demo.TestMain main
    信息: UserBean{userName='ZhangSan4', age='null'}

    解:根据日志打印可知,执行顺序为

    1、application-conterxt.xml解析 
    2、BeanDefinition
    3、执行MyBeanFactoryPostProcessor
    4、执行MyBeanPostProcessor.before()
    5、执行MyBeanPostProcessor1.before()
    6、init-method
    7、执行MyBeanPostProcessor.after()
    8、执行MyBeanPostProcessor1.after()
    

    相关文章

      网友评论

          本文标题:Spring源码-PostProcessor

          本文链接:https://www.haomeiwen.com/subject/hfbpyltx.html