美文网首页
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