BeanPostProcessor和InstantiationAwareBeanPostProcessor详解

由于前面有一篇文章解释了spring如何解决bean循环依赖的问题,里面涉及了SmartInstantiationAwareBeanPostProcessor的切面,这次干脆把BeanPostProcessor和InstantiationAwareBeanPostProcessor一起讲了,也好巩固下知识点

基础知识:
Bean创建过程中的“实例化”与“初始化”名词

1、实例化(Instantiation): 要生成对象, 对象还未生成.
2、初始化(Initialization): 对象已经生成.,赋值操作。

BeanPostProcessor

BeanPostProcessor是spring非常重要的拓展接口,例如aop通过拓展接口生产代理bean等。接口有两个方法:

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

ApplicationContext类型的容器会自动发现和注册该类型的bean,通过BeanPostProcessor可以对bean进行定制化,接口作用域是所有bean创建。
1、postProcessBeforeInitialization触发时机在bean实例化(Instantiation)之后,所有初始化(Initialization)动作(包括 InitializingBean#afterPrpertiesSet() 和 定制化init-method())以前。
2、postProcessAfterInitialization触发时机在bean实例化(Instantiation)之后,所有初始化(Initialization)动作(包括 InitializingBean#afterPrpertiesSet() 和 定制化init-method())以后。同时还会在InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation 和 FactoryBean(bean工厂)获得bean时候调用

BeanPostProcessor 的Demo

由于ApplicationContext可以自动发现并注册BeanPostProcessor,如下使用ApplicationContext类型容器实现一个简单demo。

1 public class BeanPostProcessorTest {
 2 
 3     private ApplicationContext applicationContext ;
 4 
 5     @Before
 6     public void beforeApplicationContext(){
 7         /**
 8          * ApplicationContext 自动注册 BeanPostProcessor 
 9          *  不需要手动注册
10          * */
11         applicationContext = new ClassPathXmlApplicationContext("ioc-beanPostProcessor.xml") ;
12     }
13 
14     @Test
15     public void test(){
16         Bean bean = applicationContext.getBean("bean", Bean.class) ;
17         System.out.println(bean);
18     }
19 
20     @After
21     public void after(){
22         ((ClassPathXmlApplicationContext)applicationContext).close();
23     }
24 }

BeanPostProcessorTest.java
1 public class Bean {
 2 
 3     public Bean(){
 4 
 5     }
 6 
 7     public Bean(String name){
 8         System.out.println("构造函数被调用啦");
 9         this.name = name ;
10     }
11 
12     private String name ;
13 
14 
15     public String getName() {
16         return name;
17     }
18 
19     public void setName(String name) {
20         this.name = name;
21     }
22 
23     @Override
24     public String toString() {
25         return "Bean{" +
26                 "name='" + name + '\'' +
27                 '}';
28     }
29 }

Bean.java
1 public class LogicBeanPostProcessor implements BeanPostProcessor {
 2 
 3     @Nullable
 4     @Override
 5     public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
 6         System.out.println("LogicBeanPostProcessor.postProcessAfterInitialization 执行啦 beanName = " + beanName);
 7         return bean;
 8     }
 9 
10     @Nullable
11     @Override
12     public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
13         System.out.println("LogicBeanPostProcessor.postProcessBeforeInitialization 执行啦 beanName = " + beanName);
14         return bean;
15     }
16 }

LogicBeanPostProcessor.java

结果:

构造函数被调用啦
LogicBeanPostProcessor.postProcessBeforeInitialization 执行啦 beanName = bean
LogicBeanPostProcessor.postProcessAfterInitialization 执行啦 beanName = bean
Bean{name=‘zhouxiaoxing’}

BeanPostProcessor源码分析:注册时机和触发点

1、注册BeanPostProcessor

在AbstractApplicationContext容器启动的refresh()会注册BeanPostProcessor,源码如下:

@Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // Prepare this context for refreshing.
            prepareRefresh();

            // Tell the subclass to refresh the internal bean factory.
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // Prepare the bean factory for use in this context.
            prepareBeanFactory(beanFactory);

            try {
                // Allows post-processing of the bean factory in context subclasses.
                postProcessBeanFactory(beanFactory);

                // Invoke factory processors registered as beans in the context.
                invokeBeanFactoryPostProcessors(beanFactory);

                // Register bean processors that intercept bean creation.
                // 注册BeanPostProcessor 在bean创建的时候进行拦截
               registerBeanPostProcessors(beanFactory);

                // Initialize message source for this context.
                initMessageSource();

                // Initialize event multicaster for this context.
                initApplicationEventMulticaster();

                // Initialize other special beans in specific context subclasses.
                onRefresh();

                // Check for listener beans and register them.
                registerListeners();

                // Instantiate all remaining (non-lazy-init) singletons.
                finishBeanFactoryInitialization(beanFactory);

                // Last step: publish corresponding event.
                finishRefresh();
            }

            catch (BeansException ex) {
                if (logger.isWarnEnabled()) {
                    logger.warn("Exception encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
                }

                // Destroy already created singletons to avoid dangling resources.
                destroyBeans();

                // Reset 'active' flag.
                cancelRefresh(ex);

                // Propagate exception to caller.
                throw ex;
            }

            finally {
                // Reset common introspection caches in Spring's core, since we
                // might not ever need metadata for singleton beans anymore...
                resetCommonCaches();
            }
        }
    }

        ......

    /**
     * Instantiate and invoke all registered 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) {

        /**
         * 此时bean的定义加载已经完成,但是还没有实例化。 获得所有BeanPostProcessor bean对应的beanName
         */
        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

        /**
         * 注册日志BeanPostProcessor, 检测注册的bean是否为spring基础服务类并打印日志
         */
        // 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));

        /**
         * 当有注册多个BeanPostProcessor接口时会按顺序进行,即 实现PriorityOrdered->实现Ordered->普通类型接口->内部系统MergedBeanDefinitionPostProcessor
         */
        // Separate between BeanPostProcessors that implement PriorityOrdered,
        // Ordered, and the rest.
        List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
        List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
        List<String> orderedPostProcessorNames = new ArrayList<>();
        List<String> nonOrderedPostProcessorNames = new ArrayList<>();
        for (String ppName : postProcessorNames) {
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {

               /**
                 * 通过beanFactory.getBean(), 将会提前初始化BeanPostProcessor类型实例
                 */
                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(priorityOrderedPostProcessors, beanFactory);
        registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

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

        // Now, register all regular BeanPostProcessors.
        List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
        for (String ppName : nonOrderedPostProcessorNames) {
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            nonOrderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

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

        /**
         * ApplicationListener探测器,当bean实现ApplicationListener接口时自动注册监听
         */
        // Re-register post-processor for detecting inner beans as ApplicationListeners,
        // moving it to the end of the processor chain (for picking up proxies etc).
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
    }

    /**
     * 按照给定Ordered的顺序排序
     */
    private static void sortPostProcessors(List<?> postProcessors, ConfigurableListableBeanFactory beanFactory) {
        Comparator<Object> comparatorToUse = null;
        if (beanFactory instanceof DefaultListableBeanFactory) {
            comparatorToUse = ((DefaultListableBeanFactory) beanFactory).getDependencyComparator();
        }
        if (comparatorToUse == null) {
            comparatorToUse = OrderComparator.INSTANCE;
        }
        postProcessors.sort(comparatorToUse);
    }

    /**
     * Register the given BeanPostProcessor beans.
     */
    private static void registerBeanPostProcessors(
            ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {

        for (BeanPostProcessor postProcessor : postProcessors) {
            beanFactory.addBeanPostProcessor(postProcessor);
        }
    }

跟进AbstractBeanFactory#addBeanPostProcessor

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

    /** Indicates whether any InstantiationAwareBeanPostProcessors have been registered. */
    private volatile boolean hasInstantiationAwareBeanPostProcessors;

    /** Indicates whether any DestructionAwareBeanPostProcessors have been registered. */
    private volatile boolean hasDestructionAwareBeanPostProcessors;


    /**
     * 所有的BeanPostProcessor接口实例保存于CopyOnWriteArrayList中
     * 1、一个实例只注册一次
     * 2、通过hasInstantiationAwareBeanPostProcessors设置,判定是否存在InstantiationAwareBeanPostProcessor接口实例,为后续执行做判断
     * 3、通过hasDestructionAwareBeanPostProcessors设置,判定是否存在DestructionAwareBeanPostProcessor接口实例,为后续执行做判断
     */
    @Override
    public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
        Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
        // Remove from old position, if any
        this.beanPostProcessors.remove(beanPostProcessor);
        // Track whether it is instantiation/destruction aware
        if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
            this.hasInstantiationAwareBeanPostProcessors = true;
        }
        if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
            this.hasDestructionAwareBeanPostProcessors = true;
        }
        // Add to end of list
        this.beanPostProcessors.add(beanPostProcessor);
    }

总结;
(1)、BeanPostProcessor注册的入口在AbstractApplicationContext容器启动的refresh()的AbstractApplicationContext#registerBeanPostProcessors。

(2)、AbstractApplicationContext进而委派PostProcessorRegistrationDelegate#registerBeanPostProcessors实现注册。

(3)、当有注册多个BeanPostProcessor接口时会按顺序进行,即 实现PriorityOrdered->实现Ordered->普通类型接口->内部系统MergedBeanDefinitionPostProcessor。而同种类型也会进行排序,按顺序注册。

(4)、BeanPostProcessor类型实例会通过BeanFactory#getBean()提前初始化。

触发BeanPostProcessor方法

触发BeanPostProcessor有很多入口,首先分析几个入口后续的再补上。

触发(1)AbstractAutowireCapableBeanFactory#createBean 中:

/**
     * Central method of this class: creates a bean instance,
     * populates the bean instance, applies post-processors, etc.
     * @see #doCreateBean
     */
    @Override
    protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
            throws BeanCreationException {

        if (logger.isTraceEnabled()) {
            logger.trace("Creating instance of bean '" + beanName + "'");
        }
        RootBeanDefinition mbdToUse = mbd;

        // Make sure bean class is actually resolved at this point, and
        // clone the bean definition in case of a dynamically resolved Class
        // which cannot be stored in the shared merged bean definition.
        Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
        if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
            mbdToUse = new RootBeanDefinition(mbd);
            mbdToUse.setBeanClass(resolvedClass);
        }

        // Prepare method overrides.
        try {
            mbdToUse.prepareMethodOverrides();
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                    beanName, "Validation of method overrides failed", ex);
        }

        try {
            // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
            Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
            if (bean != null) {
                return bean;
            }
        }
        catch (Throwable ex) {
            throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
                    "BeanPostProcessor before instantiation of bean failed", ex);
        }

        try {
            // bean 创建
            Object beanInstance = doCreateBean(beanName, mbdToUse, args);
            if (logger.isTraceEnabled()) {
                logger.trace("Finished creating instance of bean '" + beanName + "'");
            }
            return beanInstance;
        }
        catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
            // A previously detected exception with proper bean creation context already,
            // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
            throw ex;
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                    mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
        }
    }

    /**
     * Actually create the specified bean. Pre-creation processing has already happened
     * at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.
     * <p>Differentiates between default bean instantiation, use of a
     * factory method, and autowiring a constructor.
     * @param beanName the name of the bean
     * @param mbd the merged bean definition for the bean
     * @param args explicit arguments to use for constructor or factory method invocation
     * @return a new instance of the bean
     * @throws BeanCreationException if the bean could not be created
     * @see #instantiateBean
     * @see #instantiateUsingFactoryMethod
     * @see #autowireConstructor
     */
    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
            throws BeanCreationException {

        // Instantiate the bean.
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        if (instanceWrapper == null) {
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }

        // 省略......

        // Initialize the bean instance.
        Object exposedObject = bean;
        try {
            // 根据加载到的bean definition给 bean赋值
            populateBean(beanName, mbd, instanceWrapper);
            // 调用bean初始化方法,执行了initMethod 和 afterPropertiesSet
            exposedObject = initializeBean(beanName, exposedObject, mbd);
        }
        catch (Throwable ex) {
            if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
                throw (BeanCreationException) ex;
            }
            else {
                throw new BeanCreationException(
                        mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
            }
        }

        // 省略......

        return exposedObject;
    }

跟进AbstractAutowireCapableBeanFactory#initializeBean方法:
注:其中BeanFactoηAware 作用:实现 BeanFactoηAware 接口的 bean 可以直接访问 Spring 容器,被容器创建以后,它会拥有一个指向 Spring 容器的引用,可以利用该bean根据传入参数动态获取被spring工厂加载的bean(beanFactory让你可以不依赖注入方式即注解,随意的读取IOC容器里面的对象,不过beanFactory本身还是要注入的)

/**
     * Initialize the given bean instance, applying factory callbacks
     * as well as init methods and bean post processors.
     * <p>Called from {@link #createBean} for traditionally defined beans,
     * and from {@link #initializeBean} for existing bean instances.
     * @param beanName the bean name in the factory (for debugging purposes)
     * @param bean the new bean instance we may need to initialize
     * @param mbd the bean definition that the bean was created with
     * (can also be {@code null}, if given an existing bean instance)
     * @return the initialized bean instance (potentially wrapped)
1、经常会需要用到beanFactory对象,这就需要实现BeanFactoryAware这种类型的接口,它有一个setBeanFactory方法
 2、在xml中配置bean 的时候,我们也可以指定initMethod方法
 3、在bean类定义的时候可以实现InitializingBean,提供一个afterPropertiesSet方法的实现
     * @see BeanNameAware
     * @see BeanClassLoaderAware
     * @see BeanFactoryAware
     * @see #applyBeanPostProcessorsBeforeInitialization
     * @see #invokeInitMethods
     * @see #applyBeanPostProcessorsAfterInitialization
     */
    protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
        // 1、工厂factory类 接口回调
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                invokeAwareMethods(beanName, bean);
                return null;
            }, getAccessControlContext());
        }
        else {
         //这里判断是BeanFactoryAware, ServletContextAware之类的aware类型,如果是的话就执行对于的Aware方法,把beanFactory servletContext之类的依赖set进去
            invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
            // 2、//如果实现了BeanPostProcessor接口 这里会执行postProcessBeforeInitialization方法,BeanPostProcessor前置执行
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }

        try {
            // 3、InitializingBean接口方法 or 自定义 init method 执行,开始执行initMethod 和 afterPropertiesSet方法
            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()) {
            // 4、BeanPostProcessor后置执行
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

        return wrappedBean;
    }

对应回调方法:

1 private void invokeAwareMethods(final String beanName, final Object bean) {
 2         if (bean instanceof Aware) {
 3             if (bean instanceof BeanNameAware) {
 4                 ((BeanNameAware) bean).setBeanName(beanName);
 5             }
 6             if (bean instanceof BeanClassLoaderAware) {
 7                 ClassLoader bcl = getBeanClassLoader();
 8                 if (bcl != null) {
 9                     ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
10                 }
11             }
12             if (bean instanceof BeanFactoryAware) {
13                 ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
14             }
15         }
16     }
17 
18     /**
19      * Give a bean a chance to react now all its properties are set,
20      * and a chance to know about its owning bean factory (this object).
21      * This means checking whether the bean implements InitializingBean or defines
22      * a custom init method, and invoking the necessary callback(s) if it does.
23      * @param beanName the bean name in the factory (for debugging purposes)
24      * @param bean the new bean instance we may need to initialize
25      * @param mbd the merged bean definition that the bean was created with
26      * (can also be {@code null}, if given an existing bean instance)
27      * @throws Throwable if thrown by init methods or by the invocation process
28      * @see #invokeCustomInitMethod
29      */
30     protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
31             throws Throwable {
32 
33         boolean isInitializingBean = (bean instanceof InitializingBean);
34         if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
35             if (logger.isTraceEnabled()) {
36                 logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
37             }
38             if (System.getSecurityManager() != null) {
39                 try {
40                     AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {				//afterPropertiesSet方法,初始化bean的时候执行,可以针对某个具体的bean进行配置。afterPropertiesSet 必须实现 InitializingBean接口。实现 InitializingBean接口必须实现afterPropertiesSet方法。
41                         ((InitializingBean) bean).afterPropertiesSet();
42                         return null;
43                     }, getAccessControlContext());
44                 }
45                 catch (PrivilegedActionException pae) {
46                     throw pae.getException();
47                 }
48             }
49             else {
50                 ((InitializingBean) bean).afterPropertiesSet();
51             }
52         }
53 
54         if (mbd != null && bean.getClass() != NullBean.class) {
55             String initMethodName = mbd.getInitMethodName();
56             if (StringUtils.hasLength(initMethodName) &&
57                     !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
58                     !mbd.isExternallyManagedInitMethod(initMethodName)) {
59                 invokeCustomInitMethod(beanName, bean, mbd);
60             }
61         }
62     }
63 
64     @Override
65     public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
66             throws BeansException {
67 
68         Object result = existingBean;
69         for (BeanPostProcessor processor : getBeanPostProcessors()) {
70             Object current = processor.postProcessBeforeInitialization(result, beanName);
71             if (current == null) {
72                 return result;
73             }
74             result = current;
75         }
76         return result;
77     }
78 
79     @Override
80     public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
81             throws BeansException {
82 
83         Object result = existingBean;
84         for (BeanPostProcessor processor : getBeanPostProcessors()) {
85             Object current = processor.postProcessAfterInitialization(result, beanName);
86             if (current == null) {
87                 return result;
88             }
89             result = current;
90         }
91         return result;
92     }

initializeBean对应的方法

总结如下:

(1.1)、由此可见BeanPostProcessor的一个触发入口在AbstractAutowireCapableBeanFactory#createBean,最终至AbstractAutowireCapableBeanFactory#initializeBean。

(1.2)、AbstractAutowireCapableBeanFactory#initializeBean不但会触发BeanPostProcessor回掉方法,并且还会按顺序执行bean生命周期:

factory类型接口(BeanNameAware#setBeanName)
factory类型接口(BeanClassLoaderAware#setBeanClassLoader)
factory类型接口(BeanFactoryAware#setBeanFactory)
BeanPostProcessor#postProcessBeforeInitialization
InitializingBean和自定义的init-method
BeanPostProcessor#postProcessAfterInitialization
大步骤看:
1.spring先根据beanDefinition创建出了bean 的实例

2.执行了populateBean方法 把属性和依赖都注入了

3.执行了 initializeBean(beanName, exposedObject, mbd);方法 这里面才进行了Aware相关方法,afterPropertiesSet 和 initMethod 方法的调用
可见这3种方法调用又都是在bean实例已经创建好,且属性值和依赖的其他bean实例都已经注入以后 才得到调用的

4.后面的代码可以看出 Aware相关方法最先执行,afterPropertiesSet 第二执行 ,initMethod 方法最后执行

另外多说一句 afterPropertiesSet方法是很有用的,比如 AOP事务管理用到的类,TransactionProxyFactoryBean 就是利用afterPropertiesSet方法事先把事务管理器
TransactionManager的代理类对象给生成好了,后面调用FactoryBean对象的getObject方法的时候,就直接把这个代理对象返回出去了。

InstantiationAwareBeanPostProcessor

InstantiationAwareBeanPostProcessor继承自BeanPostProcessor 是spring非常重要的拓展接口,代表这bean的一段生命周期: 实例化(Instantiation)

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {

    @Nullable
    default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        return null;
    }

    default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        return true;
    }

    @Nullable
    default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
            throws BeansException {

        return null;
    }

    @Deprecated
    @Nullable
    default PropertyValues postProcessPropertyValues(
            PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {

        return pvs;
    }

}

由于InstantiationAwareBeanPostProcessor继承自BeanPostProcessor, 其他接口可以参考BeanPostProcessor,这里针对多出接口说明一下:

1、postProcessBeforeInstantiation调用时机为bean实例化(Instantiation)之前 如果返回了bean实例, 则会替代原来正常通过target bean生成的bean的流程. 典型的例如aop返回proxy对象. 此时bean的执行流程将会缩短, 只会执行

BeanPostProcessor#postProcessAfterInitialization接口完成初始化。

2、postProcessAfterInstantiation调用时机为bean实例化(Instantiation)之后和任何初始化(Initialization)之前。

3、postProcessProperties调用时机为postProcessAfterInstantiation执行之后并返回true, 返回的PropertyValues将作用于给定bean属性赋值. spring 5.1之后出现以替换@Deprecated标注的postProcessPropertyValues

4、postProcessPropertyValues已经被标注@Deprecated,后续将会被postProcessProperties取代。

这里总结下主要四个方法执行顺序,实例化前(postProcessBeforeInstantiation),实例化后(postProcessAfterInstantiation),初始化前(postProcessBeforeInitialization),初始化后(postProcessAfterInitialization)

InstantiationAwareBeanPostProcessor的Demo

1 public class InstantiationAwareBeanPostProcessorTest {
 2     private ApplicationContext applicationContext ;
 3 
 4     @Before
 5     public void beforeApplicationContext(){
 6         /**
 7          * ApplicationContext 自动注册 BeanPostProcessor、InstantiationAwareBeanPostProcessor、BeanFactoryPostProcessor
 8          *  不需要手动注册
 9          * */
10         applicationContext = new ClassPathXmlApplicationContext("ioc-InstantiationAwareBeanPostProcessor.xml") ;
11     }
12 
13     @Test
14     public void test(){
15         Bean bean = applicationContext.getBean("bean", Bean.class) ;
16         System.out.println(bean);
17     }
18 
19     @After
20     public void after(){
21         ((ClassPathXmlApplicationContext)applicationContext).close();
22     }
23 }

InstantiationAwareBeanPostProcessorTest.java
1 public class LogicInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
 2 
 3     @Override
 4     public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
 5         System.out.print("beanName:"+beanName+"执行..postProcessAfterInstantiation\n");
 6         
 7         // 会影响postProcessProperties 是否执行,返回false不执行
 8         return true;
 9     }
10 
11     @Override
12     public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
13         System.out.print("beanName:"+beanName+"执行..postProcessBeforeInstantiation\n");
14         if(beanClass == Bean.class){
15 
16             //利用 其 生成动态代理
17             Enhancer enhancer = new Enhancer();
18             enhancer.setSuperclass(beanClass);
19             enhancer.setCallback(new BeanMethodInterceptor());
20             Bean bean = (Bean)enhancer.create();
21             System.out.print("返回动态代理\n");
22             return bean ;
23         }
24         return null ;
25     }
26 
27     @Override
28     public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
29         System.out.print("beanName:"+beanName+"执行..postProcessProperties\n");
30         return pvs;
31     }
32 
33     //************************************** BeanPostProcessor **********************************************
34 
35     @Override
36     public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
37         System.out.print("beanName:"+beanName+"执行..postProcessAfterInitialization\n");
38         return bean;
39     }
40 
41     @Override
42     public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
43         System.out.print("beanName:"+beanName+"执行..postProcessBeforeInitialization\n");
44         return bean;
45     }
46 }

LogicInstantiationAwareBeanPostProcessor.java
1 public class BeanMethodInterceptor implements MethodInterceptor {
2     @Override
3     public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
4         System.out.println("目标方法前:" + method+"\n");
5         Object object = methodProxy.invokeSuper(o, objects);
6         System.out.println("目标方法后:" + method+"\n");
7         return object;
8     }
9 }

BeanMethodInterceptor.java
1 public class Bean {
 2     public Bean(){
 3 
 4     }
 5     public Bean(String name){
 6         System.out.println("构造函数被调用啦");
 7         this.name = name ;
 8     }
 9 
10     private String name ;
11 
12     public String getName() {
13         return name;
14     }
15 
16     public void setName(String name) {
17         this.name = name;
18     }
19 
20     @Override
21     public String toString() {
22         return "Bean{" +
23                 "name='" + name + '\'' +
24                 '}';
25     }
26 }

Bean.java

结果:

beanName:bean执行…postProcessBeforeInstantiation
返回动态代理
beanName:bean执行…postProcessAfterInitialization
目标方法前:public java.lang.String com.nancy.ioc.Bean.toString()
目标方法后:public java.lang.String com.nancy.ioc.Bean.toString()
Bean{name=‘null’}

触发时机

1.postProcessBeforeInstantiation 调用时机:
BeanDefinition创建Bean的开端是在createBean()方法也就是流水线的开始处

@Override
	protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
		...省略
		try {
			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
					"BeanPostProcessor before instantiation of bean failed", ex);
		}

看这段英文注释: Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.

给BeanPostProcessor一个机会去返回一个代理对象. 就是在流水线doCreateBean()生成对象之前, 给用户自定义返回一个对象的机会.

再看看resolveBeforeInstantiation(beanName, mbdToUse)是如何处理自定义返回对象的.

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
		Object bean = null;
		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
			// Make sure bean class is actually resolved at this point.
			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				Class<?> targetType = determineTargetType(beanName, mbd);
				if (targetType != null) {
					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
					if (bean != null) {
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
	}

判断是有有InstantiationAwareBeanPostProcessor的BeanPostProcessor
有则调用的是InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation()实例化前置处理方法,也就是在Bean没有生成之前执行。(注意:这里所说的是Bean未生成指的是Bean没有走spring定义创建Bean的流程,也就是doCreateBean()方法。)
如果postProcessBeforeInstantiation()返回的对象不为空, 那么对象的生成阶段直接完成了
接着调用postProcessAfterInitialization()[初始化后置处理] 处理这个对象.
如果为空?则走流水线doCreateBean()创建对象, 对象初始化.

2.postProcessAfterInstantiation调用时机

上文resolveBeforeInstantiation()没有返回bean.则走流水线创建Bean

doCreateBean(beanName, mbdToUse, args)创建对象,会经过populateBean(beanName, mbd, instanceWrapper)方法。

populateBean(beanName, mbd, instanceWrapper)依次执行postProcessAfterInstantiation() 与postProcessPropertyValues()

  try {
            this.populateBean(beanName, mbd, instanceWrapper);
            exposedObject = this.initializeBean(beanName, exposedObject, mbd);
        } catch (Throwable var18) {
            if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {
                throw (BeanCreationException)var18;
            }

            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18);
        }

接着前面讲的postProcessBeforeInitialization和postProcessAfterInitialization

3.postProcessBeforeInitialization调用时机

doCreateBean(beanName, mbdToUse, args)创建对象,会经过initializeBean(beanName, exposedObject, mbd);方法。

initializeBean(beanName, exposedObject, mbd); 会首先执行 postProcessBeforeInitialization()方法

4.postProcessAfterInitialization

initializeBean(beanName, exposedObject, mbd); 会首先执行 postProcessAfterInitialization()方法

总结:

实例化—>初始化

BeanPostProcessor定义的方法是在对象初始化过程中做处理,场景如返回自定义bean。
InstantiationAwareBeanPostProcessor定义的方法是在对象实例化过程中做处理
会形成两种执行流程完成BeanDefinition 创建Bean.场景如返回自定义bean并设置属性以及执行自定义方法

postProcessBeforeInstantiation()–自定义对象–>postProcessAfterInitialization();
postProcessBeforeInstantiation() -->postProcessAfterInstantiation–>postProcessBeforeInitialization()–>postProcessAfterInitialization()
我们看出:postProcessBeforeInstantiation一定执行, postProcessAfterInitialization一定执行.

关于那些方法影响那些方法的执行,可以看下这篇Spring之InstantiationAwareBeanPostProcessor接口介绍

切面aop

BeanPostProcessor的bean初始化前置处理和初始化后置处理方法均委派其子类实现,其实现子类有很多,其中创建AOP代理对象的子类是AbstractAutoProxyCreator,它实现了postProcessAfterInitialization方法。

下面具体可以分析一下AbstractAutoProxyCreator类的postProcessAfterInitialization方法。

 public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
        if (bean != null) {
        	// 根据给定的bean的class和name构建一个key
            Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
            if (this.earlyProxyReferences.remove(cacheKey) != bean) {
            // 如果它适合被代理,则需要封装指定的bean
                return this.wrapIfNecessary(bean, beanName, cacheKey);
            }
        }

        return bean;
    }

    protected Object getCacheKey(Class<?> beanClass, @Nullable String beanName) {
        if (StringUtils.hasLength(beanName)) {
            return FactoryBean.class.isAssignableFrom(beanClass) ? "&" + beanName : beanName;
        } else {
            return beanClass;
        }
    }

    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
            return bean;
        } else if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
            return bean;
            // 判断是否是基础设施类,或者是否配置了无需自动代理。如果是,缓存key并直接返回
            //shouldSkip()方法中对当前bean判断是否应该略过时,其主要做了两件事:
           // a. 为当前bean生成需要代理的Advisors;
           // b. 判断生成的Advisor是否为AspectJPointcutAdvisor类型。
            //因而实际上判断略过的过程就是判断是否为AspectJPointcutAdvisor,
            //判断这个类的原因在于Spring Aop的切面和切点的生成也可以通过在xml文件中使用
           // <aop:config/>标签进行。这个标签最终解析得到的Adivsor类型就是
           // AspectJPointcutAdvisor类型的,因为其在解析<aop:config/>的时候就已经生成了Advisor,
           // 因而这里需要对这种类型的Advisor进行略过。
            
        } else if (!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) {
        // Spring Aop在为目标bean获取需要进行代理的切面逻辑的时候最终得到的是Advisor,
        //这里Advice表示的是每个切面逻辑中使用@Before、@After和@Around等需要织入的代理方法。
            Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
            if (specificInterceptors != DO_NOT_PROXY) {
                this.advisedBeans.put(cacheKey, Boolean.TRUE);
                // 创建代理
                Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
                this.proxyTypes.put(cacheKey, proxy.getClass());
                return proxy;
            } else {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return bean;
            }
        } else {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }
    }

创建代理对象Spring提供了两种方式,JDK动态代理和Cglib AOP代理。
(关于advisor概念参考文章Spring中的Advisor,Advice,Pointcut,Advised)
进入createAopProxy()方法,发现这个方法最终在DefaultAopProxyFactory类中被实现。

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
// isOptimize:用来控制通过CGLIB创建的代理是否使用激进的优化策略
// isProxyTargetClass:为true时,目标类本身被代理而不是目标类的接口,即使用CGLIB创建代理
// hasNoUserSuppliedProxyInterfaces:是否存在代理接口
        if (!config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
            return new JdkDynamicAopProxy(config);
        } else {
         // 如果是接口或是一个代理对象就要jdk动态代理
            Class<?> targetClass = config.getTargetClass();
          
            if (targetClass == null) {
                throw new AopConfigException("TargetSource cannot determine target class: Either an interface or a target is required for proxy creation.");
            } else {
                return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config));
            }
        }
    }

如果目标对象实现了接口,默认情况下会采用JDK动态代理,但也可以通过配置(proxy-target-class=true)强制使用CGLIB。

如果目标对象没有实现接口,必须采用CGLIB库。

JdkDynamicAopProxy类实现了InvocationHandler接口,我们知道InvocationHandler是JDK动态代理的核心,生成的代理对象的方法调用都会委派到invoke()方法中。

JdkDynamicAopProxy的invoke()方法的核心逻辑为:

先获取应用到目标方法上的拦截器链(Interceptor Chain),如果有拦截器则应用拦截器(before、after、afterReturning等),并执行连接点(JoinPoint)。如果没有拦截器,则直接反射执行连接点。

JDK动态代理与CGLIB的区别:

JDK动态代理只能对实现了接口的类生成代理,不能针对类。

CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法,所以该类和方法要保证可以被继承与覆盖。

补:
首先看下getAdvicesAndAdvisorsForBean这个方法:名字很明显用来获取当前bean的advisor和adices的,这些都是生成代理类时需要的信息。

protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
        List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
        if (advisors.isEmpty()) {
            return DO_NOT_PROXY;
        }
        return advisors.toArray();
    }

然后调用findEligibleAdvisors,获取配置的advisor信息

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
        List<Advisor> candidateAdvisors = findCandidateAdvisors();
        List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
        extendAdvisors(eligibleAdvisors);
        if (!eligibleAdvisors.isEmpty()) {
            eligibleAdvisors = sortAdvisors(eligibleAdvisors);
        }
        return eligibleAdvisors;
    }

来看下findCandidateAdvisors方法,最终调用BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans

public List<Advisor> findAdvisorBeans() {
        // Determine list of advisor bean names, if not cached already.
        String[] advisorNames = null;
        synchronized (this) {
            advisorNames = this.cachedAdvisorBeanNames;
            if (advisorNames == null) {
                // Do not initialize FactoryBeans here: We need to leave all regular beans
                // uninitialized to let the auto-proxy creator apply to them!
                advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                        this.beanFactory, Advisor.class, true, false);
                this.cachedAdvisorBeanNames = advisorNames;
            }
        }
        if (advisorNames.length == 0) {
            return new LinkedList<>();
        }

        List<Advisor> advisors = new LinkedList<>();
        for (String name : advisorNames) {
            if (isEligibleBean(name)) {
                if (this.beanFactory.isCurrentlyInCreation(name)) {
                    
                }
                else {
                    try {
                        advisors.add(this.beanFactory.getBean(name, Advisor.class));
                    }
                    catch (BeanCreationException ex) {
                      throw ex;
                    }
                }
            }
        }
        return advisors;
    }

1)首先获取spring管理的Advisor类型的类名称。

2)通过beanFactory获取该bean对应的实体类,并装入advisors。

生成的这个advisor可是相当复杂,这里我们以事务advisor为例说明
在这里插入图片描述
可以看到这个advisor包含了advice(aop中的通知),pointcut(aop中的切入点),
在这里插入图片描述
advice是TransactionInterceptor,这个通知是用来管理spring的事务的可以看到包含事务的管理器等管理事务的属性,具体的方法见TransactionAspectSupport.invokeWithinTransaction
pointcut是TransactionAttributeSourcePointcut,

public boolean matches(Method method, @Nullable Class<?> targetClass) {
        if (targetClass != null && TransactionalProxy.class.isAssignableFrom(targetClass)) {
            return false;
        }
        TransactionAttributeSource tas = getTransactionAttributeSource();
        return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
    }
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页