BeanPostProcessor原理--使用講解

《Spring源碼解析》筆記html

BeanPostProcessor原理學習

在學習BeanPostProcessor的原理學習完以後,對Spring如何使用充滿好奇,嘗試使用例子進行理解,如下記錄過程:spring

一、使用ApplicationContextAware,能夠指定,在當前函數中獲取到容器上下文,具體使用舉例以下:app

@Component
public class Dog implements ApplicationContextAware {

    //@Autowired
    private ApplicationContext context;

    public Dog(){
        System.out.println("dog constructor...");
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        // TODO Auto-generated method stub
        this.context = applicationContext; } }

二、在Dog類中經過使用變量context便可獲取Spring的容器上下文,可是具體如何實現?ide

     ApplicationContextAware自己並無繼承BeanPostProcess,只繼承Aware接口 函數

public interface ApplicationContextAware extends Aware {

    /**
     * Set the ApplicationContext that this object runs in.
     * Normally this call will be used to initialize the object.
     * <p>Invoked after population of normal bean properties but before an init callback such
     * as {@link org.springframework.beans.factory.InitializingBean#afterPropertiesSet()}
     * or a custom init-method. Invoked after {@link ResourceLoaderAware#setResourceLoader},
     * {@link ApplicationEventPublisherAware#setApplicationEventPublisher} and
     * {@link MessageSourceAware}, if applicable.
     * @param applicationContext the ApplicationContext object to be used by this object
     * @throws ApplicationContextException in case of context initialization errors
     * @throws BeansException if thrown by application context methods
     * @see org.springframework.beans.factory.BeanInitializationException
     */
    void setApplicationContext(ApplicationContext applicationContext) throws BeansException;

}

  經過代碼運行,能夠看到調用,該setApplicationContext是經過類ApplicationContextAwareProcessor實現,post

  查看ApplicationContextAwareProcessor:學習

class ApplicationContextAwareProcessor implements BeanPostProcessor {}

當容器中的Bean賦值後,會遍歷容器中的BeanPostProcessor ,挨個執行,天然會執行到ApplicationContextAwareProcessor 的postProcessBeforeInitialization()方法。this

在其中執行的是this.invokeAwareInterfaces(bean)函數,查看invokeAwareInterfaces()函數代碼:spa

private void invokeAwareInterfaces(Object bean) {
        if (bean instanceof Aware) {
            if (bean instanceof EnvironmentAware) {
                ((EnvironmentAware)bean).setEnvironment(this.applicationContext.getEnvironment());
            }

            if (bean instanceof EmbeddedValueResolverAware) {
                ((EmbeddedValueResolverAware)bean).setEmbeddedValueResolver(this.embeddedValueResolver);
            }

            if (bean instanceof ResourceLoaderAware) {
                ((ResourceLoaderAware)bean).setResourceLoader(this.applicationContext);
            }

            if (bean instanceof ApplicationEventPublisherAware) {
                ((ApplicationEventPublisherAware)bean).setApplicationEventPublisher(this.applicationContext);
            }

            if (bean instanceof MessageSourceAware) {
                ((MessageSourceAware)bean).setMessageSource(this.applicationContext);
            }

            if (bean instanceof ApplicationContextAware) {
                ((ApplicationContextAware)bean).setApplicationContext(this.applicationContext);
            }
        }

    }

三、從代碼中能夠看出code

     該函數只會執行實現Aware接口的Bean,咱們的實現類Dog實現的是ApplicationContextAware

    即會執行其相關的代碼,自動爲Dog中變量進行賦值。

四、引伸學習Aware 

     自定義組件實現xxxAware;在建立對象的時候,會調用接口規定的方法注入相關組件;Aware;

     把Spring底層一些組件注入到自定義的Bean中; 

    xxxAware:部分Aware接口的功能使用xxxProcessor;

  ApplicationContextAware==》ApplicationContextAwareProcessor;

  例如BeanNameAware接口的實現見4.3;

  4.1 Aware的子接口如圖所示:

   

  4.2 舉例Aware的使用方式

  

@Component
public class Red implements ApplicationContextAware,BeanNameAware,EmbeddedValueResolverAware {
    private ApplicationContext applicationContext;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        // TODO Auto-generated method stub
        System.out.println("傳入的ioc:"+applicationContext);
        this.applicationContext = applicationContext;
    }
    @Override
    public void setBeanName(String name) {
        // TODO Auto-generated method stub
        System.out.println("當前bean的名字:"+name);
    }
    //StringValueResolver:Resolve the given String value, for example parsing placeholders.
    @Override
    public void setEmbeddedValueResolver(StringValueResolver resolver) {
        // TODO Auto-generated method stub
        String resolveStringValue = resolver.resolveStringValue("你好 ${os.name} 我是 #{20*18}");
        System.out.println("解析的字符串:"+resolveStringValue);
    }
}

   4.2 BeanNameAware接口的實現

  首先在函數initializeBean中,會調用invokeAwareMethods函數,其中Beanpostprocess的兩個方法及初始化方法都是在該函數中進行執行。

 

 

   進入invokeAwareMethods函數

   

 

  在函數中能夠觀察到部分Aware的子接口均是在此實現。

相關文章
相關標籤/搜索