首页 > 编程语言 >Spring之Bean后处理器——InstantiationAwareBeanPostProcessor的使用与源码解析

Spring之Bean后处理器——InstantiationAwareBeanPostProcessor的使用与源码解析

时间:2023-06-28 20:01:44浏览次数:48  
标签:String Spring bean public Bean Book 源码 InstantiationAwareBeanPostProcessor name


<div class="operating">
                <a class="href-article-edit slide-toggle">版权</a>
            </div>
        </div>
    </div>
</div>
<div id="blogHuaweiyunAdvert"></div>
    <div id="blogColumnPayAdvert">
        <div class="column-group">
            <div class="column-group-item column-group0 column-group-item-one">
                <div class="item-l">
                    <a class="item-target" href="https://blog.csdn.net/u013632755/category_3193091.html" target="_blank" title="Spring" data-report-click="{"spm":"1001.2101.3001.6332"}">
                        <img class="item-target" src="/i/ll/?i=2021010218004631.jpg?x-oss-process=image/resize,m_fixed,h_224,w_224" alt="">
                        <span class="title item-target">
                            <span>
                            <span class="tit">Spring</span>
                                <span class="dec">专栏收录该内容</span>
                            </span>
                        </span>
                    </a>
                </div>
                <div class="item-m">
                    <span>12 篇文章</span>
                    <span>0 订阅</span>
                </div>
                <div class="item-r">
                        <a class="item-target article-column-bt articleColumnFreeBt" data-id="3193091">订阅专栏</a>
                </div>
            </div>
        </div>
    </div>
<article class="baidu_pl">
    <div id="article_content" class="article_content clearfix">
    <link rel="stylesheet" href="https://csdnimg.cn/release/blogv2/dist/mdeditor/css/editerView/kdoc_html_views-1a98987dfd.css">
    <link rel="stylesheet" href="https://csdnimg.cn/release/blogv2/dist/mdeditor/css/editerView/ck_htmledit_views-25cebea3f9.css">
            <div id="content_views" class="markdown_views prism-atom-one-light">
                <svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
                    <path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path>
                </svg>
                <p></p>

文章目录

  • InstantiationAwareBeanPostProcessor介绍
  • InstantiationAwareBeanPostProcessor执行流程
  • InstantiationAwareBeanPostProcessor使用
  • Book
  • Pen
  • BookProxyInstantiationAwareBeanPostProcessor
  • main
  • 全量代码
  • 执行结果
  • 源码解析
  • 总结

InstantiationAwareBeanPostProcessor介绍

InstantiationAwareBeanPostProcessor接口扩展了BeanPostProcessor子接口,提供了Bean被实例化之前、Bean实例化之后、Bean属性装配前更细粒度控制Bean创建流程的处理。

由于InstantiationAwareBeanPostProcessor扩展了BeanPostProcessor接口,所以该篇文章部分内容会与BeanPostProcessor接口的流程重合;尽管如此,也建议在看该篇文章前,先阅读关于BeanPostProcessor接口的详细介绍与源码解析:Spring之Bean后处理器——BeanPostProcessor的使用与源码解析

InstantiationAwareBeanPostProcessor接口比BeanPostProcessor新增了如下方法:

方法

描述

Object postProcessBeforeInstantiation(Class&lt;?&gt; beanClass, String beanName)

Bean实例化之前,调用此方法;该方法传入目标Bean类型与BeanName;该方法可以返回一个该Bean类型的对象,或对该Bean的一个代理对象;当该方法返回了实例化对象后,后续的所有Bean实例化与初始化的动作将不再进行。只会调用后续的BeanPostProcessor#postProcessAfterInitialization()方法。

boolean postProcessAfterInstantiation(Object bean, String beanName)

Bean实例化之后,调用此方法;该方法传入还没有装配属性的Bean对象以及BeanName。 如果该方法返回true,则将跳过后续的属性装配动作,一般应该返回true

PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)

Bean实例化之后,装配属性之前,调用此方法;该方法传入在配置期间所配的PropertyValues以及BeanName。 该方法返回的PropertyValues将最终装配到Bean对象中。

InstantiationAwareBeanPostProcessor执行流程

InstantiationAwareBeanPostProcessor流程如下:

  • 执行Bean实例化之前,执行postProcessBeforeInstantiation();
  • 执行Bean实例化之后执行postProcessAfterInstantiation();
  • 执行Bean属性装配前执行postProcessProperties();
  • Bean属性装配后执行postProcessBeforeInitialization();
  • Bean的Init相关初始化完毕后执行postProcessAfterInitialization();

下图能比较好的反应出过程:

Spring之Bean后处理器——InstantiationAwareBeanPostProcessor的使用与源码解析_实例化

InstantiationAwareBeanPostProcessor使用

接下来写个例子。全量代码会在最后贴出来,直接CV运行即可。

Book

Book类,它实现了InitializingBean接口,其afterPropertiesSet()方法仅输出一行信息用来记录执行流程;还有一个customInit()方法使其加入到Springinit-method的执行过程;该类还有一个show()方法,用来在后面的BookProxyInstantiationAwareBeanPostProcessor处理器中对原始的Book对象生成一个代理类,该代理类将对show()方法进行增强处理,用来让咱们的BeanPostProcessor能实际干点事儿。
但是由于BookProxyInstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation()返回了代理对象,所以后续Book后续的初始化都不会在进行,所以其afterPropertiesSet()customInit()方法也不会再调用。

public class Book implements InitializingBean {
    private String name;
    private String author;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public void show() {
        System.out.printf("book#show():%s\n", this);
    }

    public void customInit() {
        System.out.printf("%-85s:%s{%s}%n", "------Book#customInit", this.getClass().getSimpleName(), this);
    }

    @Override
    public String toString() {
        return "Book{" +
                "name='" + name + '\'' +
                ", author='" + author + '\'' +
                '}';
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.printf("%-85s:%s{%s}%n", "------Book#afterPropertiesSet", this.getClass().getSimpleName(), this);
    }
}
Pen

Pen类与Book类一样,它实现了InitializingBean接口,其afterPropertiesSet()方法仅输出一行信息用来记录执行流程;还有一个customInit()方法使其加入到Springinit-method的执行过程;

public class Pen implements InitializingBean {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Pen{" +
                "name='" + name + '\'' +
                '}';
    }

    public void customInit() {
        System.out.printf("%-85s:%s{%s}%n", "------Pen#customInit", this.getClass().getSimpleName(), this);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.printf("%-85s:%s{%s}%n", "------Pen#afterPropertiesSet", this.getClass().getSimpleName(), this);
    }
}
BookProxyInstantiationAwareBeanPostProcessor

BookProxyInstantiationAwareBeanPostProcessor实现了InstantiationAwareBeanPostProcessor接口;在其postProcessBeforeInstantiation()方法中对Book类型进行判断,如果是Book类型则使用CGLIB生成其代理,用来增强Book#show()方法,在其前后各打印一句话。其余方法都仅输出一条信息,用来描述其执行过程。

public class BookProxyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        System.out.printf("%-85s:%s%n", "------BookProxyInstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation", beanClass.getSimpleName());
        //判断传入的beanClass是否是Book类型
        if (Book.class.equals(beanClass)) {
            System.out.printf("\033[1;33m%-85s:对[%s]的\033[1;31mshow()\033[1;33m方法进行增强 \033[0m%n", "------BookProxyInstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation", beanClass.getSimpleName());
            //创建Book类的代理
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(Book.class);
            enhancer.setCallback((MethodInterceptor) (obj, method, args, methodProxy) -> {
                //如果不是show()方法则直接调用返回
                if (!method.equals(Book.class.getMethod("show"))) {
                    return methodProxy.invokeSuper(obj, args);
                }
                //对show()做增强处理
                System.out.printf("\033[1;33m%-70s\033[0m%n", "Book#show()执行前");
                Object result = methodProxy.invokeSuper(obj, args);
                System.out.printf("\033[1;33m%-70s\033[0m%n", "Book#show()执行后");
                return result;
            });
            Book book = (Book) enhancer.create();
            book.setName("《非暴力沟通》");
            book.setAuthor("马歇尔·卢森堡");
            return book;
        }

        return null;
    }
    
    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        System.out.printf("%-85s:%s{%s}%n", "------BookProxyInstantiationAwareBeanPostProcessor#postProcessAfterInstantiation", bean.getClass().getSimpleName(), bean);
        return true;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.printf("%-85s:%s{%s}%n", "------BookProxyInstantiationAwareBeanPostProcessor#postProcessBeforeInitialization", bean.getClass().getSimpleName(), bean);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.printf("%-85s:%s{%s}%n", "------BookProxyInstantiationAwareBeanPostProcessor#postProcessAfterInitialization", bean.getClass().getSimpleName(), bean);
        return bean;
    }

    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        System.out.printf("%-85s:%s{%s}%n", "------BookProxyInstantiationAwareBeanPostProcessor#postProcessProperties", bean.getClass().getSimpleName(), bean);
        pvs.forEach((name) -> {
            System.out.printf("%85s:%s {%s=%s}%n", "pvs", bean.getClass().getSimpleName(), name.getName(), name.getValue());
        });

        return pvs;
    }
}
main

定义一个Book类型与Pen类型的GenericBeanDefinition,将BookPencustomInit()添加到BeanDefinition中,并设置PenMutablePropertyValues用于初始化后的属性装配。
同时将BookProxyInstantiationAwareBeanPostProcessor注册到容器中。

public static void main(String[] args) {
    GenericApplicationContext context = new GenericApplicationContext();
    //注册Book的BeanDefinition
    GenericBeanDefinition bookBeanDefinition = new GenericBeanDefinition();
    bookBeanDefinition.setBeanClass(Book.class);
    bookBeanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON);//指定为单例模式
    bookBeanDefinition.setInitMethodName("customInit");//设置初始化方法
    context.registerBeanDefinition("book", bookBeanDefinition);
    //注册Pen的BeanDefinition
    GenericBeanDefinition penBeanDefinition = new GenericBeanDefinition();
    penBeanDefinition.setBeanClass(Pen.class);
    penBeanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON);//指定为单例模式
    penBeanDefinition.setInitMethodName("customInit");//设置初始化方法
    //设置pen属性
    penBeanDefinition.setPropertyValues(new MutablePropertyValues()
            .addPropertyValue(new PropertyValue("name", "英雄钢笔"))
    );
    context.registerBeanDefinition("pen", penBeanDefinition);//注册BeanDefinition
    //注册BookProxyInstantiationAwareBeanPostProcessor后处理器
    context.registerBean(BookProxyInstantiationAwareBeanPostProcessor.class);
    //刷新容器
    context.refresh();
    //获取Book的bean对象,调用show()方法
    context.getBean("book", Book.class).show();
}
全量代码


package com.baiyang.beanpostprocessor.instantiationaware;

import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.context.support.GenericApplicationContext;

import java.util.concurrent.atomic.AtomicInteger;

public class BookProxyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
    public static AtomicInteger COUNT = new AtomicInteger();

    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        System.out.printf("%-85s:%s%n", COUNT.addAndGet(1) + "------BookProxyInstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation", beanClass.getSimpleName());
        //判断传入的beanClass是否是Book类型
        if (Book.class.equals(beanClass)) {
            System.out.printf("\033[1;33m%-85s:对[%s]的\033[1;31mshow()\033[1;33m方法进行增强 \033[0m%n", COUNT.addAndGet(1) + "------BookProxyInstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation", beanClass.getSimpleName());
            //创建Book类的代理
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(Book.class);
            enhancer.setCallback((MethodInterceptor) (obj, method, args, methodProxy) -> {
                //如果不是show()方法则直接调用返回
                if (!method.equals(Book.class.getMethod("show"))) {
                    return methodProxy.invokeSuper(obj, args);
                }
                //对show()做增强处理
                System.out.printf("\033[1;33m%-70s\033[0m%n", "Book#show()执行前");
                Object result = methodProxy.invokeSuper(obj, args);
                System.out.printf("\033[1;33m%-70s\033[0m%n", "Book#show()执行后");
                return result;
            });
            Book book = (Book) enhancer.create();
            book.setName("《非暴力沟通》");
            book.setAuthor("马歇尔·卢森堡");
            return book;
        }

        return null;
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        System.out.printf("%-85s:%s{%s}%n", COUNT.addAndGet(1) + "------BookProxyInstantiationAwareBeanPostProcessor#postProcessAfterInstantiation", bean.getClass().getSimpleName(), bean);
        return true;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.printf("%-85s:%s{%s}%n", COUNT.addAndGet(1) + "------BookProxyInstantiationAwareBeanPostProcessor#postProcessBeforeInitialization", bean.getClass().getSimpleName(), bean);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.printf("%-85s:%s{%s}%n", COUNT.addAndGet(1) + "------BookProxyInstantiationAwareBeanPostProcessor#postProcessAfterInitialization", bean.getClass().getSimpleName(), bean);
        return bean;
    }

    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        System.out.printf("%-85s:%s{%s}%n", COUNT.addAndGet(1) + "------BookProxyInstantiationAwareBeanPostProcessor#postProcessProperties", bean.getClass().getSimpleName(), bean);
        pvs.forEach((name) -> {
            System.out.printf("%85s:%s {%s=%s}%n", "pvs", bean.getClass().getSimpleName(), name.getName(), name.getValue());
        });

        return pvs;
    }


    public static void main(String[] args) {
        GenericApplicationContext context = new GenericApplicationContext();
        //注册Book的BeanDefinition
        GenericBeanDefinition bookBeanDefinition = new GenericBeanDefinition();
        bookBeanDefinition.setBeanClass(Book.class);
        bookBeanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON);//指定为单例模式
        bookBeanDefinition.setInitMethodName("customInit");//设置初始化方法
        context.registerBeanDefinition("book", bookBeanDefinition);
        //注册Pen的BeanDefinition
        GenericBeanDefinition penBeanDefinition = new GenericBeanDefinition();
        penBeanDefinition.setBeanClass(Pen.class);
        penBeanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON);//指定为单例模式
        penBeanDefinition.setInitMethodName("customInit");//设置初始化方法
        //设置pen属性
        penBeanDefinition.setPropertyValues(new MutablePropertyValues()
                .addPropertyValue(new PropertyValue("name", "英雄钢笔"))
        );
        context.registerBeanDefinition("pen", penBeanDefinition);//注册BeanDefinition
        //注册BookProxyInstantiationAwareBeanPostProcessor后处理器
        context.registerBean(BookProxyInstantiationAwareBeanPostProcessor.class);
        //刷新容器
        context.refresh();
        //获取Book的bean对象,调用show()方法
        context.getBean("book", Book.class).show();
    }

    static class Book implements InitializingBean {
        private String name;
        private String author;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getAuthor() {
            return author;
        }

        public void setAuthor(String author) {
            this.author = author;
        }

        public void show() {
            System.out.printf("book#show():%s\n", this);
        }

        public void customInit() {
            System.out.printf("%-85s:%s{%s}%n", COUNT.addAndGet(1) + "------Book#customInit", this.getClass().getSimpleName(), this);
        }

        @Override
        public String toString() {
            return "Book{" +
                    "name='" + name + '\'' +
                    ", author='" + author + '\'' +
                    '}';
        }

        @Override
        public void afterPropertiesSet() throws Exception {
            System.out.printf("%-85s:%s{%s}%n", COUNT.addAndGet(1) + "------Book#afterPropertiesSet", this.getClass().getSimpleName(), this);
        }
    }

    static class Pen implements InitializingBean {
        private String name;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        @Override
        public String toString() {
            return "Pen{" +
                    "name='" + name + '\'' +
                    '}';
        }

        public void customInit() {
            System.out.printf("%-85s:%s{%s}%n", COUNT.addAndGet(1) + "------Pen#customInit", this.getClass().getSimpleName(), this);
        }

        @Override
        public void afterPropertiesSet() throws Exception {
            System.out.printf("%-85s:%s{%s}%n", COUNT.addAndGet(1) + "------Pen#afterPropertiesSet", this.getClass().getSimpleName(), this);
        }
    }
}
执行结果

Spring之Bean后处理器——InstantiationAwareBeanPostProcessor的使用与源码解析_实例化_02


从执行结果即可反应出InstantiationAwareBeanPostProcessor的执行流程:

1~3行的结果是加载Book的输出,由于BookProxyInstantiationAwareBeanPostProcessor在执行postProcessBeforeInstantiation方法之后返回了Book的代理对象,所以后续对Book的所有初始化将不再继续,调用了BeanDefinition#postProcessAfterInitialization之后就直接返回注册了。
4~10行的输出结果可以看出,Pen类的加载,由于没有任何InstantiationAwareBeanPostProcessor对其做任何处理,所以走完了所有的常规Bean加载流程。
最后三行输出执行了从容器中获取的book对象的show()方法,可以看出我们通过BookProxyInstantiationAwareBeanPostProcessor成功的改变了原本注入到容器中的Book对象,并成功对其show()方法进行了增强处理。

源码解析

spring版本:5.2.9

该节源码解析仅仅只讲关键的与InstantiationAwareBeanPostProcessor相关的位置。如果想要知其与InstantiationAwareBeanPostProcessor前后的细节,可以针对本节的所讲述的位置自行Debug进入详细阅读。

首先是Spring容器的经典入口:refresh()

Spring之Bean后处理器——InstantiationAwareBeanPostProcessor的使用与源码解析_ide_03


然后调用AbstractApplicationContext所持有的实际BeanFactory(DefaultListableBeanFactory)句柄的preInstantiateSingletons()做Bean容器的初始化工作。

Spring之Bean后处理器——InstantiationAwareBeanPostProcessor的使用与源码解析_System_04


org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons:

Spring之Bean后处理器——InstantiationAwareBeanPostProcessor的使用与源码解析_实例化_05


bean的创建流程:getBean()-&gt;doGetBean()-&gt;createBean()-&gt;doCreateBean() 我们直接定位到createBean()

Spring之Bean后处理器——InstantiationAwareBeanPostProcessor的使用与源码解析_System_06


从上面的流程可以看出,当执行了resolveBeforeInstantiation(beanName,mbdToUse)方法后,有返回bean对象,则直接return出去了。 如果没有返回bean对象,则会执行doCreateBean()进行真正的常规创建流程。

在本文章的例子中,初始化book对象的流程中BookProxyInstantiationAwareBeanPostProcessorpostProcessBeforeInstantiation()返回了book的代理对象,所以在上面的流程中,直接返回出去了,没有执行doCreateBean()方法。

接下进入resolveBeforeInstantiation(beanName,mbdToUse)

Spring之Bean后处理器——InstantiationAwareBeanPostProcessor的使用与源码解析_ide_07


org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation

Spring之Bean后处理器——InstantiationAwareBeanPostProcessor的使用与源码解析_ide_08


org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization

Spring之Bean后处理器——InstantiationAwareBeanPostProcessor的使用与源码解析_ide_09


createBean()将对象返回出去,一路回到getSingleton():

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory&lt;?&gt;)

Spring之Bean后处理器——InstantiationAwareBeanPostProcessor的使用与源码解析_System_10


可以看到此时,已经将一个经过了InstantiationAwareBeanPostProcessor处理的Bean对象注册到了BeanFactory中(在本例子里面是我们的BookProxyInstantiationAwareBeanPostProcessor创建的Book对象的代理类)。


经过以上流程可以看出,当InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation()如果返回了对象的话,那么Bean的创建流程将会直接结束返回该对象。


接下来讲InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation()不返回对象的Bean创建流程,在该例子里面是Pen的创建流程:

Spring之Bean后处理器——InstantiationAwareBeanPostProcessor的使用与源码解析_System_11


上面的流程中,由于执行了BookProxyInstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation()没有返回对象,所以会执行后面的doCreateBean()来创建对象。org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean

Spring之Bean后处理器——InstantiationAwareBeanPostProcessor的使用与源码解析_System_12

在上面的流程中,先通过反射创建了对象,然后调用populateBean()进行属性装配,属性装配后,执行Bean的初始化流程,包含了BeanPostProcessor的前后置处理、init-method相关处理。

我们知道,在InstantiationAwareBeanPostProcessor中目前还只执行了postProcessBeforeInstantiation(),还有剩下postProcessAfterInstantiation()postProcessProperties()postProcessBeforeInitialization()postProcessAfterInitialization()没有执行。

我们先看populateBean()中的逻辑:

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean

Spring之Bean后处理器——InstantiationAwareBeanPostProcessor的使用与源码解析_System_13


从上面的流程可以看出,populateBean()的流程是先调用InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation(),然后调用其InstantiationAwareBeanPostProcessor#postProcessPropertyValues(),最后进行属性的装配工作。

此时和我们前面描述的执行流程保持一致。


接下来是postProcessBeforeInitialization()postProcessAfterInitialization()的执行还没有做。

返回到上层

Spring之Bean后处理器——InstantiationAwareBeanPostProcessor的使用与源码解析_ide_14


org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition):

Spring之Bean后处理器——InstantiationAwareBeanPostProcessor的使用与源码解析_System_15


从上面的initializeBean()的流程可以看到我们首先调用了BeanPostProcessor#postProcessBeforeInitialization(),然后执行了invokeInitMethods()来处理bean的实现的InitializingBean接口的afterPropertiesSet()与自定义init-method;最后执行BeanPostProcessor#postProcessAfterInitialization();

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization

Spring之Bean后处理器——InstantiationAwareBeanPostProcessor的使用与源码解析_System_16


org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeInitMethods

Spring之Bean后处理器——InstantiationAwareBeanPostProcessor的使用与源码解析_ide_17


从上面的invokeInitMethods()可以看到包含了InitializingBean接口的处理与init-method的方法处理流程;

init-method方法最终会通过反射执行。最后就是BeanPostProcessor#postProcessAfterInitialization()方法的执行:

Spring之Bean后处理器——InstantiationAwareBeanPostProcessor的使用与源码解析_实例化_18

至此,所有的InstantiationAwareBeanPostProcessor接口涉及到的流程都执行完毕,与前面讲述的流程一样,最后就是返回到getSingleton()将最后最终的对象注册到容器中。

总结

以上通过围绕InstantiationAwareBeanPostProcessor创建一个对指定Bean对象的代理对象,对其特定方法进行代理增强的例子,来介绍了InstantiationAwareBeanPostProcessor的应用,以及描述了InstantiationAwareBeanPostProcessor的"短路"会控制到后续常规Bean的创建流程。
同时,通过对源码的浅析来对InstantiationAwareBeanPostProcessor的执行前后流程进行了讲解。


https://blog.csdn.net/u013632755/article/details/124596220

标签:String,Spring,bean,public,Bean,Book,源码,InstantiationAwareBeanPostProcessor,name
From: https://blog.51cto.com/u_12948550/6575903

相关文章

  • 深入浅出synchronized的原理与源码
    深入浅出synchronized的原理与源码1.java对象头关于锁的标识1.对象头//32bits://--------//hash:25------------>|age:4biased_lock:1lock:2(normalobject)//JavaThread*:23epoch:2age:4biased_lock:1lock:2(biasedobject......
  • 基于Xml的申明式事务开头出现ERROR org.springframework.test.context.TestContextMan
    刚开始一直查找关于第一行的错误,发现一直没有找到相关的解决方案。在看完log之后,在log中间位置发现另一个错误:FailedtointrospectClass[org.springframework.aop.aspectj.AspectJExpressionPointcut]fromClassLoader[jdk.internal.loader.ClassLoaders$AppClassLoader@639......
  • 2. SpringMVC入门案例
    1.入门案例之创建步骤‍SpringMVC的制作过程和上述流程几乎是一致的,具体的实现流程是什么?1.创建web工程(Maven结构)2.设置tomcat服务器,加载web工程(tomcat插件)3.导入坐标(SpringMVC+Servlet)4.定义处理请求的功能类(UserController)5.设置请求映射(配置映射关......
  • springboot测试时不能写个main测试含有bean方法的原因
     springboot使用bean作用是不用自己new对象,new类生成对象时,可能需要输入自定义类B作为参数,而该自定义类B可能又依赖其它需要输入自定义类C作为参数,新建对象会很麻烦,springboot的bean注入容器后,该对象不用自己定义,直接从容器中取.但用注解定义了bean后,并没有注入容......
  • SpringIOC原理
    Spring通过一个配置文件描述Bean及Bean之间的依赖关系,利用Java语言的反射功能实例化Bean并建立Bean之间的依赖关系。Spring的IoC容器在完成这些底层工作的基础上,还提供了Bean实例缓存、生命周期管理、Bean实例代理、事件发布、资源装载等高级服务。Spring容器高层视图Spring启动时......
  • SpringBean生命周期
    实例化:实例化一个Bean,也就是我们常说的new。IoC依赖注入:按照Spring上下文对实例化的Bean进行配置,也就是Ioc注入。setBeanName实现:如果这个Bean已经实现了BeanNameAware接口,会调用它实现的setBeanName(String)方法,此处传递的就是Spring配置文件中Bean的id值。BeanFactoryAware实现:如......
  • Spring ElasticSearch Date
    问题背景使用spring-data-elasticsearch:4.4.12查询数据,数据映射到对象的时候时间字段格式异常,报错如下对象和Es通过@document注解进行映射,对象中有一个时间字段@Field(type=FieldType.Date,format={},pattern=DatePattern.CHINESE_DATE_PATTERN)privateDat......
  • 一文搞懂什么是@Component和@Bean注解以及如何使用(包括与@Controller、@Service、@Re
      来源  https://blog.csdn.net/m0_51358164/article/details/126120731一文搞懂什么是@Component和@Bean注解以及如何使用......
  • Spring从基础到精通
    Spring从基础到精通(基础)spring的世界一、什么是springSpring是一种开源轻量级框架,是为了解决企业应用程序开发复杂性而创建的,Spring致力于解决JavaEE的各层解决方案,而不仅仅于某一层的方案。二、spring发展历史2003年2月Spring框架正式称为一道开源项目,Spring致力于J2EE应......
  • C#云LIS系统源码,B/S架构的实验室信息系统源码
    科技的飞速发展为实验室信息管理带来了新机遇,云计算技术的应用更是为实验室信息管理打开了新的大门。云LIS实验室信息管理系统,作为一种新型的信息化管理方案,已经在多个实验室的信息化管理中得到应用,并且具有广阔的应用前景。云LIS系统技术架构:ASP.NETCORE3.1MVC+SQLserver......