Spring - BeanPostProcessors 扩展接口

Posted 小小工匠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring - BeanPostProcessors 扩展接口相关的知识,希望对你有一定的参考价值。

文章目录


Pre

Spring Boot - 扩展接口一览


Bean的生成过程


org.springframework.beans.factory.config.BeanPostProcessor 介绍

public interface BeanPostProcessor 


	@Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException 
		return bean;
	

	@Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException 
		return bean;
	




如果BeanPostProcessors接囗的实现类被注册到ioc容器,那么该容器的每个Bean在调用初始化方法之前,都会获得该接口实现类的一个回调。

要使用BeanPostProcessord回调,就必须先在容器中注册实现该接口的类,那么如何注册呢?

  • 若使用BeanFactory,则必须要显示的调用其addBeanPostProcessor方法进行注册,参数为BeanPostProcessor现类的实例;

  • 使用ApplicationContext,那么容器会在配置文件在中自动寻找实现了 BeanPostProcessor口的Bean,然后自动注册,我们只需要配置个BeanPostProcessor现类的Bean可以了。

  • 多个的BeanPostProcessorg实现类,只要实现Ordered接口,设置order属性就可以很轻确定不同实现类的处理顺序了;

  • 接口中的两个方法都要将传入的bean回,不能返回null,如果返回的是nu么我们通过getBean将得不到目标


ApplicationContext注册Bean PostProcessor源码解析

AbstractApplicationContext#refresh

org.springframework.context.support.AbstractApplicationContext#refresh

来看下关键代码

public void refresh() throws BeansException, IllegalStateException 
	 
	........

	// Register bean processors that intercept bean creation.
	registerBeanPostProcessors(beanFactory);
 
	........
	// Instantiate all remaining (non-lazy-init) singletons.
	// 实例化剩余的所有非延迟加载单例对象
	// 在上面的registerBeanPostProcessors中已经把所有BeanPostProcessors所有对象都已经实例化过了

	//  这加载的时候会判断bean是不是 FactoryBean类型的
	//  如果是FactoryBean类型,则getBean(&beanName),这里是把FactoryBean本身的对象给实例化了,而没有调它的getObject方法;
	// 还要判断是不是SmartFactoryBean类型的,SmartFactoryBean继承了FactoryBean接口;但是它多了一个	boolean isEagerInit();方法;这个方法就是判断是否需要通过FactoryBean的getObject()生成实例;
	// 如果不是FactoryBean类型,直接getBean就行了;
	
	// 还要判断是不是SmartInitializingSingleton接口,这个接口有个afterSingletonsInstantiated方法;
	// 循环所以bean判断是不是这个类型的,只要是这个类型就调用afterSingletonsInstantiated方法;
	finishBeanFactoryInitialization(beanFactory);

	........	 
			
	

AbstractApplicationContext#registerBeanPostProcessors

先看 registerBeanPostProcessors

	/**
	 * Instantiate and register all BeanPostProcessor beans,
	 * respecting explicit order if given.
	 * <p>Must be called before any instantiation of application beans.
	 */
	protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) 
		PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
	

PostProcessorRegistrationDelegate.registerBeanPostProcessors

public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) 
		/**
		* 代码走到了这里的时候其实 BeanDefinition数据已经被加载了,只是bean还没有被实例化
		所以这个是去容器里面找到所有类型为BeanPostProcessor的beanName
		*/
		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

	
		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
		
		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

		// 优先级最高的BeanPostProcessors,这类最先调用;需要实现PriorityOrdered接口
		List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
		//内部BeanPostProcessors
		List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
		//继承了Ordered接口,优先级比上面低一点
		List<String> orderedPostProcessorNames = new ArrayList<String>();
		//这就是普通的了,优先级最低
		List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
		
		//下面的这些代码就是遍历所有postProcessorNames,按优先级排序;类型PriorityOrdered>Ordered>普通;在这个类型基础上,还要对他们的order属性就行排序;
		for (String ppName : postProcessorNames) 
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) 
				BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
				priorityOrderedPostProcessors.add(pp);
				if (pp instanceof MergedBeanDefinitionPostProcessor) 
					internalPostProcessors.add(pp);
				
			
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) 
				orderedPostProcessorNames.add(ppName);
			
			else 
				nonOrderedPostProcessorNames.add(ppName);
			
		

		// First, register the BeanPostProcessors that implement PriorityOrdered.
		sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

		// Next, register the BeanPostProcessors that implement Ordered.
		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
		for (String ppName : orderedPostProcessorNames) 
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			orderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) 
				internalPostProcessors.add(pp);
			
		
		sortPostProcessors(beanFactory, orderedPostProcessors);
		registerBeanPostProcessors(beanFactory, orderedPostProcessors);

		// Now, register all regular BeanPostProcessors.
		List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
		for (String ppName : nonOrderedPostProcessorNames) 
		//这里要注意一下了,看到没有,这个时候已经调用了getBean来生成实例对象了;
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			nonOrderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) 
				internalPostProcessors.add(pp);
			
		
		registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

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

		// 加入ApplicationListenerDetector
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
	

	/**
	 * 注册 BeanPostProcessor beans.
	 * 容器中beanPostProcessors是一个ArrayList来持有这些BeanPostProcessors
	 */
	private static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) 

		for (BeanPostProcessor postProcessor : postProcessors) 
			beanFactory.addBeanPostProcessor(postProcessor);
		
	
@Override
	public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) 
		Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
		this.beanPostProcessors.remove(beanPostProcessor);
		this.beanPostProcessors.add(beanPostProcessor);
		//将是否 hasInstantiationAwareBeanPostProcessors设置为true 
		if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) 
			this.hasInstantiationAwareBeanPostProcessors = true;
		
		if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) 
			this.hasDestructionAwareBeanPostProcessors = true;
		
	


回调BeanPostProcessors的时机源码解析

org.springframework.context.support.PostProcessorRegistrationDelegate#registerBeanPostProcessors()
	BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
		org.springframework.beans.factory.support.AbstractBeanFactory#getBean
		  org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean			

doGetBean 重点看

// Create bean instance.
if (mbd.isSingleton()) 
	sharedInstance = getSingleton(beanName, () -> 
		try 
			return createBean(beanName, mbd, args);
		
		catch (BeansException ex) 
			// Explicitly remove instance from singleton cache: It might have been put there
			// eagerly by the creation process, to allow for circular reference resolution.
			// Also remove any beans that received a temporary reference to the bean.
			destroySingleton(beanName);
			throw ex;
		
	);
	beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);

继续看 createBean

 org.springframework.context.support.PostProcessorRegistrationDelegate#registerBeanPostProcessors()
	BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
		org.springframework.beans.factory.support.AbstractBeanFactory#getBean
		  org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean	
			  org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean
					org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean

doCreateBean重点看

// Initialize the bean instance.
Object exposedObject = bean;
try 
    // 属性设置
	populateBean(beanName, mbd, instanceWrapper);
	// BeanPostProcessors两个方法都在这里面
	exposedObject = initializeBean(beanName, exposedObject, mbd);

org.springframework.context.support.PostProcessorRegistrationDelegate#registerBeanPostProcessors()
	BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
		org.springframework.beans.factory.support.AbstractBeanFactory#getBean
		  org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean	
			  org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean
					org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
						org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean

继续核心 initializeBean

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) 
		if (System.getSecurityManager() != null) 
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> 
				invokeAwareMethods(beanName, bean);
				return null;
			, getAccessControlContext());
		
		else 
		   // 检查Aware相关接口并设置相关依赖
			invokeAwareMethods(beanName, bean);
		

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) 
		   // BeanPostProcessor前置处理
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		

		try 
		   // 检查是否是InitializingBean以决定是否调用afterPropertiesSet方法 
		   // 检查是否配置有自定义的init-method方法
			invokeInitMethods(beanName, wrappedBean, mbd);
		
		catch (Throwable ex) 
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		
		if (mbd == null || !mbd.isSynthetic()) 
		   // BeanPostProcessor后置处理
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		

		return wrappedBean;
	

看下 applyBeanPostProcessorsAfterInitialization

   //注意 每一个实例对象触发这个的时候 都是执行所有的BeanPostProcessors实例对象

	@Override
	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException 

		Object result = existingBean;
		for (BeanPostProcessor processor : getBeanPostProcessors()) 
			Object current = processor.postProcessAfterInitialization(result, beanName);
			//这里是循环
			//	result =BeanPostProcessor调用执行方法;返回的对象还是result,只是有可能被某个BeanPostProcessor加强了 beanProcessor.postProcessAfterInitialization(result, beanName);
			if (current == null) 
				return result;
			
			result = current;
		
		return result;
	

扩展示例

package com.artisan.bootspringextend.testextends;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Configuration;

/**
 * @author 小工匠
 * @version 1.0
 * @description: TODO
 * @date 2022/11/27 21:22
 * @mark: show me the code , change the world
 */

@Slf4j
@Configuration
public class ExtendBeanPostProcessor  implements BeanPostProcessor 

 @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException 
        log.info("beanName: -----> postProcessBeforeInitialization",beanName);
        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException 
        log.info( "beanName:  ------> postProcessAfterInitialization",beanName);
        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    
    

    

看日志

2022-11-27 22:07:40.269  INFO 12876 --- [           main] c.a.b.t.ExtendBeanPostProcessor          : beanName: bootSpringExtendApplication-----> postProcessBeforeInitialization
2022-11-27 22:07:40.271  INFO 12876 --- [           main] c.a.b.t.ExtendBeanPostProcessor          : beanName: bootSpringExtendApplication ------> postProcessAfterInitialization
2022-11-27 22:07:40.271  INFO 12876 --- [           main] c.a.b.t.ExtendBeanPostProcessor          : beanName: org.springframework.boot.autoconfigure.AutoConfigurationPackages-----> postProcessBeforeInitialization
2022-11-27 22:07:40.272  INFO 12876 --- [           main] c.a.b.t.ExtendBeanPostProcessor          : beanName: org.springframework.boot.autoconfigure.AutoConfigurationPackages ------> postProcessAfterInitialization
2022-11-27 22:07:40.273  INFO 12876 --- [           main] c.a.b.t.ExtendBeanPostProcessor          : beanName: org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration-----> postProcessBeforeInitialization
2022-11-27 22:07:40.273  INFO 12876 --- [           main] c.a.b.t.ExtendBeanPostProcessor          : beanName: org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration Spring框架系列 - Spring和Spring框架组成

你了解Spring从Spring3到Spring5的变迁吗?

Spring全家桶笔记:Spring+Spring Boot+Spring Cloud+Spring MVC

学习笔记——Spring简介;Spring搭建步骤;Spring的特性;Spring中getBean三种方式;Spring中的标签

Spring--Spring入门

Spring框架--Spring事务管理和Spring事务传播行为