Spring源码-PostProcessor

基本定义

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模块中创建如图文件
Spring源码-PostProcessor_第1张图片

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文件


<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
信息: 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’}

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

XML解析
BeanDefinition
执行MyBeanFactoryPostProcessor
执行MyBeanPostProcessor.before
执行MyBeanPostProcessor1.before
init-method
执行MyBeanPostProcessor.after
执行MyBeanPostProcessor1.after

你可能感兴趣的:(Spring源码,spring,java,源码)