BeanPostProcessor和BeanFactoryPostProcessor浅析以及在spring初始化中回调

一、先看下BeanPostProcessor和BeanFactoryPostProcessor的各自的子类以及方法。

    1、 BeanFactoryPostProcessor,是针对整个工厂生产出来的BeanDefinition作出修改或者注册。作用于BeanDefinition时期。从名称可以看出是容器级别的,继承关系如下:
                     


   BeanFactoryPostProcessor和其子类总共二个方法,从其入参就可以看出这二个方法的具体使用,如下:

  1.    postProcessBeanDefinitionRegistry方法,此方法参数是一个BeanDefinitionRegistry,众所周知BeanDefinitionRegistry是用于
    beanDefinition注册、修改的。那么此方法在就可以在spring standard initialization后去修改一个beanDefinition、或者新增一个。
    这个类有个巨屌的实现类ConfigurationClassPostProcessor,这个类将处理configuration的类中以下注解:@Import、@PropertySource、@ComponentScan、@ImportResource、@Bean methods等。将这些注解涉及到的BeanDifinition注册到BeanDefinitionRegistry中。对ConfigurationClassPostProcessor加载兴趣的查看可以看下此链接
  2. postProcessBeanFactory方法,也是在实例化之前调用,也是读取bean定义并作出修改,比如属性修改,这个类spring也有一个巨牛的实现类PropertyPlaceholderConfigurer,这类的描述如下:将配置文件中的值注入到我们的代码中!!如数据源信息等。类解释如下:

    /**
     *
     * {@link PlaceholderConfigurerSupport} subclass that resolves ${...} placeholders
     * against {@link #setLocation local} {@link #setProperties properties} and/or system properties
     * and environment variables.
     * .....
     */

2、BeanPostProcessor 的作用于bean实例化、初始化前后执行,先看下继承关系。

 
BeanPostProcessor子类比较多,有4个拓展接口,拢共11个方法,这个11方法描述如下:

  1. BeanPostProcessors是在实例化后,初始化方法执行前、后分别执行2个方法(这里的初始化方法是init-method或者实现了InitializingBean的afterPropertiesSet方法,一般这个玩意用于读取缓存文件,初始化信息等操作)。通过这个类我们可以轻松的自定义受spring管理的bean,就是可以对bean为所欲为!

  2. InstantiationAwareBeanPostProcessor拓展了BeanPostProcessors接口,这个接口也是非常的牛掰,可以在实例化Bean前(调用postProcessBeforeInstantiation方法)、后(postProcessAfterInstantiation)提供扩展的回调接口。
    postProcessBeforeInstantiation这个返回值可以用来代替原本该生成的目标对象的实例(比如代理对象)。如果该方法的返回值代替原本该生成的目标对象,后续只有postProcessAfterInitialization方法会调用然后就直接返回了。不会在进行后续操作(可以看下AbstractAutoProxyCreator AOP代理实现)。这个类还是有一个方法:postProcessPropertyValues,这个方法是bean实例化后填充属性的时候使用,
    描述如下:

        //这个方法用来在对象实例化前直接返回一个对象(如代理对象)来代替通过内置的实例化流程创建对象;
        @Nullable
        default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
            return null;
        }
        //在对象实例化完毕执行populateBean之前 如果返回false则spring不再对对应的bean实例进行自动依赖注入。
        default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
            return true;
        }
        //这里是在spring处理完默认的成员属性,应用到指定的bean之前进行回调,可以用来检查和修改属性,最终返回的PropertyValues会应用到bean中
        //@Autowired、@Resource等就是根据这个回调来实现最终注入依赖的属性的。
        @Nullable
        default PropertyValues postProcessPropertyValues(
                PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
            return pvs;
        }
  3. SmartInstantiationAwareBeanPostProcessor又拓展了InstantiationAwareBeanPostProcessor接口,主要是供spring内部使用,接口方法描述如下:

        /**
    	 * 用来返回目标对象的类型(比如代理对象通过raw class获取proxy type 用于类型匹配)
    	 */
    	@Nullable
    	default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
    		return null;
    	}
    	/**
    	 * 这里提供一个拓展点用来解析获取用来实例化的构造器(比如未通过bean定义构造器以及参数的情况下,会根据这个回调来确定构造器)
    	 */
    	@Nullable
    	default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)throws BeansException {
            return null;
    	}
    	/**
    	 * 提前暴露bean引用,解决循环依赖
    	 */
    	default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
    		return bean;
    	}
    

     

  4. MergedBeanDefinitionPostProcessor,也是实例化后执行,主要将那些元数据缓存起来以提供后续的postProcessPropertyValues输入注入时获取。

    /***
     * 在bean实例化完毕后调用, 缓存一些meta信息提供给后续的injectValue使用
     */
        void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);
    !

     

  5. DestructionAwareBeanPostProcessor,是对象销毁的前置回调。
     

    /***
     * 销毁逻辑
     */ 
        void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException;
        //判断是否需要处理这个对象的销毁
        default boolean requiresDestruction(Object bean) {
            return true;
        }

    经过以上简单介绍,可能对这个2个processor有了简单的了解,那么我们下面开始从spring加载流程来看,这么方法在什么时候回调的!

二、processor各个方法在spring容器启动中扮演的角色,spring在加载bean无非将所有需要管理的bean定义、并注册。然后bean实例化、填充bean属性。而processor也是作用在这些步骤前后。

  1.   bean定义注册阶段,BeanDefinition阶段,对于spring工程而言,我们对于需要容器管理的bean无非通过注解、xml等方式实现,比如使用ClassPathBeanDefinitionScanner#doScan可以扫描指定包下面的类注册到容器中等,这里不做过多讨论直接跳过,spring标准初始化后,受管理的bean定义都已经被注册到容器中了,另外插一句就是beanFactory和applicationcontext有一点区别就是beanFactory不会自动收集这些BeanPostProcessor,而applicationcontext会收集这些processor到我们工厂中。(ConfigurableListableBeanFactory#addBeanPostProcessor等)。
    我们先看下PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors方法,BeanFactoryPostProcessor以及子类都是在这个方法中回调的。下面我们先看下这个方法吧
        //这个beanFactoryPostProcessors是获取手动注册的BeanFactoryPostProcessors。不是标准化的加载进来的
    	// 如:通过ApplicationContextInitializer初始化的BeanFactoryPostProcessors
    	public static void invokeBeanFactoryPostProcessors(
    			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    
    		// Invoke BeanDefinitionRegistryPostProcessors first, if any.
    		//记录处理过的家伙
    		Set<String> processedBeans = new HashSet<>();
    		//判断是否BeanDefinitionRegistry实例,因为BeanDefinitionRegistry这玩意定义一个bean的
    		if (beanFactory instanceof BeanDefinitionRegistry) {
    			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
    			//BeanFactoryPostProcessor集合
    			List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<>();
    			//BeanDefinitionRegistryPostProcessor集合
    			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList<>();
    			//硬编码注册的后置处理,自定义的BeanFactoryPostProcessor处理
                //第一步01:
    			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
    				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
    					BeanDefinitionRegistryPostProcessor registryProcessor =
    							(BeanDefinitionRegistryPostProcessor) postProcessor;
    					//执行BeanDefinitionRegistryPostProcessor的方法
    					registryProcessor.postProcessBeanDefinitionRegistry(registry);
    					registryProcessors.add(registryProcessor);
    				} else {
    					regularPostProcessors.add(postProcessor);
    				}
    			}
    
    			// Do not initialize FactoryBeans here: We need to leave all regular beans
    			// uninitialized to let the bean factory post-processors apply to them!
    			// Separate between BeanDefinitionRegistryPostProcessors that implement
    			// PriorityOrdered, Ordered, and the rest.
    			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
                  
                //第二步02:首先获取优先最高的Processors
    			// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
    			String[] postProcessorNames =
    					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    			for (String ppName : postProcessorNames) {
    				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
    					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
    					processedBeans.add(ppName);
    				}
    			}
    			sortPostProcessors(currentRegistryProcessors, beanFactory);
    			registryProcessors.addAll(currentRegistryProcessors);
    			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
    			currentRegistryProcessors.clear();
                //第三步03:获取优先次之的Processors
    			// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
    			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    			for (String ppName : postProcessorNames) {
    				if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
    					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
    					processedBeans.add(ppName);
    				}
    			}
    			sortPostProcessors(currentRegistryProcessors, beanFactory);
    			registryProcessors.addAll(currentRegistryProcessors);
    			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
    			currentRegistryProcessors.clear();
                //第四步04:最后获取优先级低的Processors
    			// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
    			boolean reiterate = true;
    			while (reiterate) {
    				reiterate = false;
    				postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    				for (String ppName : postProcessorNames) {
    					if (!processedBeans.contains(ppName)) {
    						currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
    						processedBeans.add(ppName);
    						reiterate = true;
    					}
    				}
    				sortPostProcessors(currentRegistryProcessors, beanFactory);
    				registryProcessors.addAll(currentRegistryProcessors);
    				invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
    				currentRegistryProcessors.clear();
    			}
                //第五步05:
    			// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
    			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
    			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    		}else {
    			// Invoke factory processors registered with the context instance.
    			invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
    		}
             //第六步06
    		// Do not initialize FactoryBeans here: We need to leave all regular beans
    		// uninitialized to let the bean factory post-processors apply to them!
    		String[] postProcessorNames =
    				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
    
    		// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
    		// Ordered, and the rest.
    		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    		List<String> orderedPostProcessorNames = new ArrayList<>();
    		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    		for (String ppName : postProcessorNames) {
    			if (processedBeans.contains(ppName)) {
    				// skip - already processed in first phase above
    			}
    			else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
    				priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
    			}
    			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
    				orderedPostProcessorNames.add(ppName);
    			}
    			else {
    				nonOrderedPostProcessorNames.add(ppName);
    			}
    		}
    
    		// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
    		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
    
    		// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
    		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
    		for (String postProcessorName : orderedPostProcessorNames) {
    			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    		}
    		sortPostProcessors(orderedPostProcessors, beanFactory);
    		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
    
    		// Finally, invoke all other BeanFactoryPostProcessors.
    		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
    		for (String postProcessorName : nonOrderedPostProcessorNames) {
    			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    		}
    		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
    
    		// Clear cached merged bean definitions since the post-processors might have
    		// modified the original metadata, e.g. replacing placeholders in values...
    		beanFactory.clearMetadataCache();
    	}

    这里面我分为了6大步:
    第一步:这里其实一般 走不到的,因为beanFactoryPostProcessors是空的,这里的beanFactoryPostProcessors值不是标准化加载过来,而是一些类似于ApplictionContextInitialiazer方法加载processor的。比如:

    public class ApplicationContextInitializerDemo implements ApplicationContextInitializer {
        @Override
        public void initialize(ConfigurableApplicationContext applicationContext) {
            applicationContext.addBeanFactoryPostProcessor(
                    new ConfigurationWarningsPostProcessor(getChecks()));
        }
    }

    第二步至第第四步:这里的代码处理逻辑基本一样的,先从BeanFactory#getBeanNamesForType方法中找出所有BeanDefinitionRegistryPostProcessor类型的,然后根据实现类的优先级执行postProcessBeanDefinitionRegistry方法。为什么要getBeanNamesForType3次呢?因为优先级高实现类在执行postProcessBeanDefinitionRegistry方法时可能会定义一个BeanDefinitionRegistryPostProcessor的实现类,
    这里我们介绍一个spring对BeanDefinitionRegistryPostProcessor的实现类ConfigurationClassPostProcessor,这个类实现了PriorityOrdered,用于处理打了@Configuration标签的Class。ConfigurationClassParser会对这个类进行解析。会解析以下标签:
    处理@PropertySource标签,用来解析属性文件并设置到Environment中。
    处理@ComponentScan标签,扫描package下的所有Class并进行解析注册。
    处理@Import标签。
    处理@ImportResource标签。
    处理@Bean标签......
    第五步:没什么好说的就是执行BeanDefinitionRegistryPostProcessor的父类方法postProcessBeanFactory。
    第六部到最后:收集所有实现了BeanFactoryPostProcessor的类,根据优先级执行postProcessBeanFactory方法,这个时候可能有疑问就是为什么不也查找3次呢?因为参数啊!!!BeanDefinitionRegistryPostProcessor中方法的参数是一个BeanDefinitionRegistry,而BeanFactoryPostProcessor的参数是一个BeanFactory。BeanDefinitionRegistry是干什么的?是BeanDefinition注册、修改。所以人家可以新注册一个BeanDefinition!!!但是你BeanFactory可以么!!!

  2. Bean的实例化前后:
     在实例化、初始化前后我们的BeanPostProcessor都已经被方法registerBeanPostProcessors注册到BeanFactory的子类AbstractBeanFactory集合中.

    /** BeanPostProcessors to apply in createBean */
    	private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<>();

    先看下在实例化前后spring是如何回调的,直接到最终的方法createBean方法,这个方法做了创建bean实例、填充bean实例:

    protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
    			throws BeanCreationException {
    		/***
                     * ...代码省略 
                     */
    		try {
    			//实例化前调用,给BeanPostProcessor(InstantiationAwareBeanPostProcessor)一个机会返回代理来代替真正的实例
    			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
    			if (bean != null) {
    				return bean;
    			}
    		}
    		/***
                     * ...代码省略 
                     */
    		try {
                        //实例化、填充属性、processor回调
    			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
    			return beanInstance;
    		}
                    /***
                     * ...代码省略 
                     */	
    	}

    这个方法有2个方法一个是resolveBeforeInstantiation方法,用于执行InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation,这个方法在上面有过解释,是用来生成一个Bean实例或者代理,不为空则执行完BeanPostProcessor#postProcessAfterInitialization就直接返回了。
    另一个方法是AbstractAutowireCapableBeanFactory#doCreateBean,这个方法代码和注释如下:

    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
    			throws BeanCreationException {
    		       /***
                            * ...代码省略 
                            */
                            //bean的实例化代码~~~
    	                //执行MergedBeanDefinitionPostProcessor的方法,
    			//实例化后调用postProcessMergedBeanDefinition 比如其中一个实现就是将需要注解的元数据 放到Map中供 属性注入时使用
    			applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
    	               /***
                            * ...代码省略 
                            */   
                            //实例化后调用getEarlyBeanReference 为了避免后期循环依赖 可以在bean初始化完成前 将创建实例的Objectfactory加入工厂
    			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    		// Initialize the bean instance.
    		Object exposedObject = bean;
    		try {
    			//填充bean,可能产生依赖其他bean  则递归
    			populateBean(beanName, mbd, instanceWrapper);
    			//调用初始化方法 如init-method、实现InitializingBean的类
    			exposedObject = initializeBean(beanName, exposedObject, mbd);
    		}
    	       /***
                    * ...代码省略 
                    */ 
    		return exposedObject;
    	}

    那么实例化前后方法都调用完毕。

  3. Bean属性填充:主要有2个方法,先看填充属性方法populateBean():此方法在填充属性之前,如果返回false则不在执行属性填充操作!如果返回true则回调postProcessPropertyValues方法进行属性注入!这里面的缓存的元数据来源上一个MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition的缓存。这个可以去看下AutowiredAnnotationBeanPostProcessor。

    protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    		/***
                     * 代码省略...
                     */ 
    		//在填充属性之前,给 InstantiationAwareBeanPostProcessor最后一个机会 修改bean状态的机会。
    		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
    			for (BeanPostProcessor bp : getBeanPostProcessors()) {
    				if (bp instanceof InstantiationAwareBeanPostProcessor) {
    					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
    					//执行postProcessAfterInstantiation 在实例话后 填充属性前
    					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
    						continueWithPropertyPopulation = false;
    						break;
    					}
    				}
    			}
    		}
                    /***
                     * 代码省略...
                     */     
    		//初始化后处理器
    		boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
    		boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
    
    		if (hasInstAwareBpps || needsDepCheck) {
    			if (pvs == null) {
    				pvs = mbd.getPropertyValues();
    			}
    			PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
    			if (hasInstAwareBpps) {
    				for (BeanPostProcessor bp : getBeanPostProcessors()) {
    					if (bp instanceof InstantiationAwareBeanPostProcessor) {
    						InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
    						pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
    						if (pvs == null) {
    							return;
    						}
    					}
    				}
    			}
    			if (needsDepCheck) {
    				checkDependencies(beanName, mbd, filteredPds, pvs);
    			}
    		}
    
    		if (pvs != null) {
    			applyPropertyValues(beanName, mbd, bw, pvs);
    		}
    	}

     

  4. 初始化方法执行前后:这里的初始化方法 如init-method、实现InitializingBean的afterPropertiesSet方法。分别在这前后回调了BeanPostProcessor的2个方法,如下:

    protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
    		/***
                     * 代码省略。。。
                     */     
                    //前置执行
    		Object wrappedBean = bean;
    		if (mbd == null || !mbd.isSynthetic()) {
    			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    		}
    
    		try {
    			invokeInitMethods(beanName, wrappedBean, mbd);
    		}
    
    		/***
                     * 代码省略。。。
                     */
                    //后置回调
    		if (mbd == null || !mbd.isSynthetic()) {
    			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    		}
    
    		return wrappedBean;
    	}

    至此,bean实例化、初始化已经完成,各个processors也在相应的地方进行了回调。

 

  • 10
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值