BeanPostProcessor原理--使用讲解

《Spring源码解析》笔记

BeanPostProcessor原理学习

在学习BeanPostProcessor的原理学习完之后,对Spring如何使用充满好奇,尝试使用例子进行理解,以下记录过程:

1、使用ApplicationContextAware,可以指定,在当前函数中获取到容器上下文,具体使用举例如下:

@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; } }

2、在Dog类中通过使用变量context即可获取Spring的容器上下文,但是具体如何实现?

     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实现,

  查看ApplicationContextAwareProcessor:

class ApplicationContextAwareProcessor implements BeanPostProcessor {}

当容器中的Bean赋值后,会遍历容器中的BeanPostProcessor ,挨个执行,自然会执行到ApplicationContextAwareProcessor 的postProcessBeforeInitialization()方法。

在其中执行的是this.invokeAwareInterfaces(bean)函数,查看invokeAwareInterfaces()函数代码:

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);
            }
        }

    }

3、从代码中可以看出

     该函数只会执行实现Aware接口的Bean,我们的实现类Dog实现的是ApplicationContextAware

    即会执行其相关的代码,自动为Dog中变量进行赋值。

4、引申学习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的子接口均是在此实现。

原文地址:https://www.cnblogs.com/mayang2465/p/12098434.html