BeanPostProcessor浅析


写在前面

注:本文章使用的 SpringBoot 版本为 2.2.4.RELEASE,其 Spring 版本为 5.2.3.RELEASE

前言

BeanPostProcessor 提供 Spring Bean 初始化前和初始化后的 生命周期回调,分别对应 postProcessBeforeInitialization 以及 postProcessAfterInitialization 方法,允许对关心的 Bean 进行 扩展,甚至是替换。

BeanPostProcessor接口定义
public interface BeanPostProcessor {

	//Bean初始化前生命周期回调方法
	@Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

	//Bean初始化后生命周期回调方法
	@Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

}
BeanPostProcessor注册与源码分析

在Spring上下文刷新刷新时会触发BeanPostProcessor的注册。

AbstractApplicationContext#refresh刷新方法有12大步骤:其中就涉及到BeanPostProcessor的注册。
本篇就着重分析下registerBeanPostProcessors方法

public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
		//获取当前BeanFactory下BeanPostProcessor名称集合
		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
//下面代码主要分三大部分:
//1、先将实现了PriorityOrdered接口的BeanPostProcessor注册到IoC容器中
//2、再将实现了Ordered接口的BeanPostProcessor注册到IoC容器中
//3、最后将无序的BeanPostProcessor注册到IoC容器中
BeanPostProcessors.
		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

		// 优先有序BeanPostProcessor集合
		List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		//内部BeanPostProcessor集合
		List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
		// 有序BeanPostProcessor名称集合
		List<String> orderedPostProcessorNames = new ArrayList<>();
		// 无序BeanPostProcessor名称集合
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
		 //如果当前BeanPostProcessor实现了PriorityOrdered接口
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
				//如果当前BeanPostProcessor实现了PriorityOrdered接口,将其添加到有序BeanPostProcessor集合
				priorityOrderedPostProcessors.add(pp);
				//如果pp实现了MergedBeanDefinitionPostProcessor,将其添加到内部BeanPostProcessor集合
				if (pp instanceof MergedBeanDefinitionPostProcessor) {
					internalPostProcessors.add(pp);
				}
			}
			//如果当前BeanPostProcessor实现了Ordered接口,将其添加到有序BeanPostProcessor名称集合
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
			//最后将无序的添加到无序BeanPostProcessor名称集合
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// 为优先有序BeanPostProcessor名称集合排序
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		//将优先有序BeanPostProcessor注入到IoC容器
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

		// 注册实现了Order接口的BeanPostProcessors
		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
		for (String ppName : orderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			orderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		//排序
		sortPostProcessors(orderedPostProcessors, beanFactory);
		// 注册到IoC容器
		registerBeanPostProcessors(beanFactory, orderedPostProcessors);

		// 最后 注册普通BeanPostProcessors
		List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
		for (String ppName : nonOrderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			nonOrderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

		// 排序内部BeanPostProcessor
		sortPostProcessors(internalPostProcessors, beanFactory);
		// 注册内部BeanPostProcessor
		registerBeanPostProcessors(beanFactory, internalPostProcessors);

		// 注册ApplicationListenerDetector
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
	}

上面注册BeanPostProcessor的源码虽然有些多,但是还是有迹可循,大致分为四部分:

  • 1、先将实现了PriorityOrdered接口的BeanPostProcessor 排序 然后注册到IoC容器中
  • 2、再将实现了Ordered接口的BeanPostProcessor排序 然后注册到IoC容器中
  • 3、最后将无序的BeanPostProcessor注册到IoC容器中
  • 4、将实现了MergedBeanDefinitionPostProcessor接口的BeanPostProcessor排序后 注册到IoC容器中
常见BeanPostProcessor及用途
Bean名称Bean实例使用场景
org.springframework.context.annotation.internalConfigurationBeanNameGeneratorConfigurationClassPostProcessor对象处理Spring配置类
org.springframework.context.annotation.internalCommonAnnotationProcessorCommonAnnotationBeanPostProcessor对象(条件激活)处理JSR-250注解,如@PostConstruct/@PreDestroy
org.springframework.context.annotation.internalAutowiredAnnotationProcessorAutowiredAnnotationBeanPostProcessor对象处理@Autowired、@Value等注解
org.springframework.context.event.internalEventListenerProcessorEventListenerMethodProcessor处理@EventLIstener标注的Spring事件监听方法
org.springframework.context.event.internalEventListenerFactoryDefaultEventListenerFactory对象@EventListener事件监听方法适配为ApplicationListener
org.springframework.context.annotation.internalPersistenceAnnotationProcessorPersistenceAnnotationBeanPostProcessor对象(条件激活)处理JPA注解场景

这些BeanPostProcessor注册时机与AnnotationConfigUtils有关。

AnnotatedBeanDefinitionReader构造函数中触发这些BeanPostProcessor的注册过程,代码如下

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
		Assert.notNull(environment, "Environment must not be null");
		this.registry = registry;
		this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
//这里开始注册与注解有关的BeanPostProcessor		
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
	}

AnnotationConfigUtils#registerAnnotationConfigProcessors

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
			BeanDefinitionRegistry registry, @Nullable Object source) {

		DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
		if (beanFactory != null) {
			if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
				beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
			}
			if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
				beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
			}
		}

		Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

		if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
			def.setSource(source);
			//注册ConfigurationClassPostProcessor
			beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
			def.setSource(source);
			//注册AutowiredAnnotationBeanPostProcessor
			beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
		if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
			def.setSource(source);
			//注册CommonAnnotationBeanPostProcessor
			beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		// 条件运行的话 注册PersistenceAnnotationBeanPostProcessor
		if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition();
			try {
				def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
						AnnotationConfigUtils.class.getClassLoader()));
			}
			catch (ClassNotFoundException ex) {
				//省略异常
			}
			def.setSource(source);
			//注册PersistenceAnnotationBeanPostProcessor
			beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
			def.setSource(source);
			//注册EventListenerMethodProcessor
			beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
		}

		if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
			def.setSource(source);
			//注册DefaultEventListenerFactory
			beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
		}

		return beanDefs;
	}
InstantiationAwareBeanPostProcessor调用时机

InstantiationAwareBeanPostProcessor单拎出来说,是因为它在Spring Bean生命周期中扮演着很重要的角色。

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {

	//bean实例化前回调,该方法可以阻断Bean正常的创建过程,稍后在源码中分析
	@Nullable
	default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		return null;
	}

	//bean实例化后回调,若它返回false 将影响Bean属性赋值,详见populateBean方法
	default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
		return true;
	}

	//设置Bean属性值,在Spring Bean生命周期中 为Bean属性赋值那里有使用
	@Nullable
	default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
			throws BeansException {

		return null;
	}

	//与上面postProcessProperties基本相同.设置Bean属性值,在Spring Bean生命周期中 为Bean属性赋值那里有使用 
	@Deprecated
	@Nullable
	default PropertyValues postProcessPropertyValues(
			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {

		return pvs;
	}

}

通过DefaultListableBeanFactory#getBean代码逻辑可知,scope无论是singleton、prototype还是request、session等,最终都是由createBean触发Bean的创建。因此我们直接进到这个方法里分析下实现思路

AbstractAutowireCapableBeanFactory#createBean

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		//省略日志输出
		RootBeanDefinition mbdToUse = mbd;

		//将字符串类型的beanClassName解析为Class
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}

		
		try {
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			//省略异常信息
		}

		try {
	       // 这里就是我们分析的重点了 ⭐️
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			//⭐️ 注意这个逻辑:如果postProcessBeforeInstantiation方法返回非null 则将返回值作为创建的Bean。并中断正常的创建流程
			if (bean != null) {
				return bean;
			}
		}
		catch (Throwable ex) {
			//省略异常信息
		}

		try {
		    //真正创建Bean的逻辑 实例化Bean对象,为Bean属性赋值等,这里暂不展开
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			//省略日志输出
			return beanInstance;
		}
		catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {//省略异常信息
	}

总结下上面代码主要实现逻辑:
1、从bd中解析出Bean Class
2、执行Bean初始化回调

  • 如果Bean初始化前回调 返回对象不为空 将其作为待创建的Bean,此时创建Bean流程终止

3、若Bean初始化前回调返回null,那么执行正常创建Bean的逻辑

@Nullable
	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
		Object bean = null;
    //一般情况下 mbd.beforeInstantiationResolved=null ,因此会进到这个if条件里
		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
			//条件一 synthetic默认值是false 一般都会成立
      //条件二 成立 说明存在 InstantiationAwareBeanPostProcessors 
			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        //targetType获取逻辑
        //1. mbd中指定了工厂方法
        //  1.1 如果是实例方法,则targetType就是实例方法对应的class
        //  1.2 如果是静态方法,则targetType就是mbd对应的BeanClass
        //2. mbd中未指定工厂方法,则targetType就是mbd对应的BeanClass
				Class<?> targetType = determineTargetType(beanName, mbd);
				if (targetType != null) {
                //调用实例化前操作
					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
					if (bean != null) {
               //调用实例化后操作 这里是无差别的调用BeanPostProcessor初始化后方法 这里不再展开
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
	}
   @Nullable
	protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
           //条件成立 说明存在InstantiationAwareBeanPostProcessor
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
             // postProcessBeforeInstantiation默认实现返回null
				Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
				if (result != null) {
					return result;
				}
			}
		}
		return null;
	}
BeanPostProcessor的简单使用

首先定义一个实体类

@Data
@ToString
public class User {

    private String name;

    private Integer age;


    public User() {
    }

    public User(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
}

创建两个BeanPostProcessor

public class MyInstantiationBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        if (ObjectUtils.nullSafeEquals("user", beanName) && User.class.equals(beanClass)) {
            System.out.println("执行到MyInstantiationBeanPostProcessor");
            return new User();
        }
        return null;
    }
}

它实现了InstantiationAwareBeanPostProcessor并重写了初始化前回调,处理逻辑为:如果当前待创建的对象类型是User并且beanName=user,那么中断该Bean的正常创建流程,并返回无参User对象

public class MyInstantiationBeanPostProcessor2 implements BeanPostProcessor {

    private DefaultListableBeanFactory beanFactory;

    public MyInstantiationBeanPostProcessor2(DefaultListableBeanFactory beanFactory) {
        this.beanFactory = beanFactory;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (ObjectUtils.nullSafeEquals("user", beanName) && User.class.equals(bean.getClass())) {
            System.out.println("执行到MyInstantiationBeanPostProcessor2");
            BeanDefinition bd = beanFactory.getBeanDefinition(beanName);
            if (BeanPostProcessDemo.class.equals(bd.getSource())) { // 通过 source 判断来
                // 属性(存储)上下文
                String name = (String) bd.getAttribute("name");
                User user = (User) bean;
                user.setName(name);
            }
        }
        return bean;
    }

}

它实现了BeanPostProcessor并重写了初始化后回调,处理逻辑为:如果当前待创建的对象类型是User,beanName=user并且来源为BeanPostProcessDemo类,那么将bd中附加属性作为name属性的值

public class BeanPostProcessDemo {

    public static void main(String[] args) {
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(User.class);
        //为bd设置name、age属性
        beanDefinitionBuilder.addPropertyValue("name", "wojiushiwo");
        beanDefinitionBuilder.addPropertyValue("age", 20);
        // 获取 AbstractBeanDefinition
        AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
        // 附加属性
        beanDefinition.setAttribute("name", "我是附加属性");
        // 当前 BeanDefinition 来自哪里(辅助作用)
        beanDefinition.setSource(BeanPostProcessDemo.class);

        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
		//添加BeanPostProcessor
        beanFactory.addBeanPostProcessor(new MyInstantiationBeanPostProcessor());
        beanFactory.addBeanPostProcessor(new MyInstantiationBeanPostProcessor2(beanFactory));

        // 注册 User 的 BeanDefinition
        beanFactory.registerBeanDefinition("user", beanDefinition);

        User user = beanFactory.getBean("user", User.class);

        System.out.println(user);

    }
}

输出结果:

执行到MyInstantiationBeanPostProcessor
执行到MyInstantiationBeanPostProcessor2
User(name=我是附加属性, age=null)

以上就是本章讨论的主要内容了,如您在阅读过程中发现有错误,还望指出,感谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值