zoukankan      html  css  js  c++  java
  • Spring源码解析(三) -- registerBeanPostProcessors(beanFactory)

      本节分析下 refresh()中的 registerBeanPostProcessors(beanFactory);方法

      

    public interface BeanPostProcessor {
    
    	/**
    	 * Apply this BeanPostProcessor to the given new bean instance <i>before</i> any bean
    	 * initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
    	 * or a custom init-method). The bean will already be populated with property values.
    	 * The returned bean instance may be a wrapper around the original.
    	 * @param bean the new bean instance
    	 * @param beanName the name of the bean
    	 * @return the bean instance to use, either the original or a wrapped one;
    	 * if {@code null}, no subsequent BeanPostProcessors will be invoked
    	 * @throws org.springframework.beans.BeansException in case of errors
    	 * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
    	 */
    	Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
    
    	/**
    	 * Apply this BeanPostProcessor to the given new bean instance <i>after</i> any bean
    	 * initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
    	 * or a custom init-method). The bean will already be populated with property values.
    	 * The returned bean instance may be a wrapper around the original.
    	 * <p>In case of a FactoryBean, this callback will be invoked for both the FactoryBean
    	 * instance and the objects created by the FactoryBean (as of Spring 2.0). The
    	 * post-processor can decide whether to apply to either the FactoryBean or created
    	 * objects or both through corresponding {@code bean instanceof FactoryBean} checks.
    	 * <p>This callback will also be invoked after a short-circuiting triggered by a
    	 * {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method,
    	 * in contrast to all other BeanPostProcessor callbacks.
    	 * @param bean the new bean instance
    	 * @param beanName the name of the bean
    	 * @return the bean instance to use, either the original or a wrapped one;
    	 * if {@code null}, no subsequent BeanPostProcessors will be invoked
    	 * @throws org.springframework.beans.BeansException in case of errors
    	 * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
    	 * @see org.springframework.beans.factory.FactoryBean
    	 */
    	Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
    
    }
    

      BeanPostProcessor的作用是一个 在BeanDefinition实例化成一个真正的对象后,在该对象的初始化前和初始化后做一些工作。它和BeanFactoryPostProcess不同, BeanFactoryPostProcess一般是改变下某个BeanDefinition,而不是真的对象。

      跟着代码,发现实际调用的是 PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);

      

    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
    
    		// Register BeanPostProcessorChecker that logs an info message when
    		// a bean is created during BeanPostProcessor instantiation, i.e. when
    		// a bean is not eligible for getting processed by all BeanPostProcessors.
    		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
    		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
    
    		// Separate between BeanPostProcessors that implement PriorityOrdered,
    		// Ordered, and the rest.
    		List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
    		List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
    		List<String> orderedPostProcessorNames = new ArrayList<String>();
    		List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
    

      其实跟上一节的beanFactoryPostProcessor过程类似,在查找 BeanPostProcessor的Bean 名字时,都是按照 PriorityOrdered, Ordered, 和没有实现这两个接口的普通类的顺序,依次实例化和初始化生成这些bean,并且注册到beanFactory中

      AbstractBeanFactory中的方法  addBeanPostProcessor,注意是 先 remove再 add

         @Override
    	public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
    		Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
    		this.beanPostProcessors.remove(beanPostProcessor);
    		this.beanPostProcessors.add(beanPostProcessor);
    		if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
    			this.hasInstantiationAwareBeanPostProcessors = true;
    		}
    		if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
    			this.hasDestructionAwareBeanPostProcessors = true;
    		}
    	}
    

       InstantiationAwareBeanPostProcessor 这是一个值得注意的BeanPostProcessor,它的接口定义如下

      

    public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor { 
    
        Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException;
        
        boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException;//动态代理就是用的这个
        
        PropertyValues postProcessPropertyValues(
                PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException;//填充属性的方法,比如@AutoWired @Resources @Value
    }

      

      他的实现类有哪些呢?

      1  AnnotationAwareAspectJAutoProxyCreator  动态代理

      2  AutowiredAnnotationBeanPostProcessor      解决@AutoWired注解的

      3  CommonAnnotationBeanPostProcessor             

       

      回到registerBeanPostProcessors方法中 里面有一个特别需要注意的地方

    if (pp instanceof MergedBeanDefinitionPostProcessor) {
    				internalPostProcessors.add(pp);
    			}
    

      如果某一个BeanPostProcessor实现了MergedBeanDefinitionPostProcessor这个接口,把它单独的放到 internalPostProcessors这个list中保存起来,并且在实例化,并注册到了beanFactory之后,最后再做一次把这些MergedBeanDefinitionPostProcessor注册进去。

       MergedBeanDefinitionPostProcessor 的作用就是负责把一个Bean的@AutoWired或者@Resource等注解的信息缓存起来留着后来使用

    // Finally, re-register all internal BeanPostProcessors.
            sortPostProcessors(beanFactory, internalPostProcessors);
            registerBeanPostProcessors(beanFactory, internalPostProcessors);

    所以,我们之前说注册时先remove再add,这样就能保证这些 internal BeanPostProcessors肯定是在AbstractBeanFactory中保存所有beanPostProcessor的最后。

      MergedBeanDefinitionPostProcessor的实现类有哪些呢?

      比较常见的有两个 AutowiredAnnotationBeanPostProcessor, CommonAnnotationBeanPostProcessor

      AutowiredAnnotationBeanPostProcessor就是用来处理一个spring bean中autowired注解的,而 CommonAnnotationBeanPostProcessor是处理resource注解的。resource注解是java的不是spring的。

      下一节,会分析beanFactory实例化的代码,就能够看到beanPostProcessor是怎么使用的了。

    总结

      BeanPostProcesssor最值得记忆的两个实现类

      1 InstantiationAwareBeanPostProcessor 既能处理属性值填充,也能处理动态代理

      2  MergedBeanDefinitionPostProcessor 专门收集自动注入等注解,并缓存起来

  • 相关阅读:
    html 中 url、scr、href、rel、rev
    MIME 和文件扩展名
    视频文件的容器格式和编码格式
    原型与原型链
    属性特征
    可选参数
    函数的定义(函数是值)
    闭包
    实现异步加载js文件及加载完成后回调
    前端工程打开速度优化的循序渐进总结
  • 原文地址:https://www.cnblogs.com/juniorMa/p/13707011.html
Copyright © 2011-2022 走看看