Spring之Bean后处理器——InstantiationAwareBeanPostProcessor的使用与源码解析
文章目录
- 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<?> 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()
;
下图能比较好的反应出过程:
InstantiationAwareBeanPostProcessor使用
接下来写个例子。全量代码会在最后贴出来,直接CV运行即可。
Book
Book
类,它实现了InitializingBean
接口,其afterPropertiesSet()
方法仅输出一行信息用来记录执行流程;还有一个customInit()
方法使其加入到Spring
的init-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);}@Overridepublic String toString() {return "Book{" +"name='" + name + '\'' +", author='" + author + '\'' +'}';}@Overridepublic void afterPropertiesSet() throws Exception {System.out.printf("%-85s:%s{%s}%n", "------Book#afterPropertiesSet", this.getClass().getSimpleName(), this);}
}
Pen
Pen
类与Book
类一样,它实现了InitializingBean
接口,其afterPropertiesSet()
方法仅输出一行信息用来记录执行流程;还有一个customInit()
方法使其加入到Spring
的init-method
的执行过程;
public class Pen implements InitializingBean {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Pen{" +"name='" + name + '\'' +'}';}public void customInit() {System.out.printf("%-85s:%s{%s}%n", "------Pen#customInit", this.getClass().getSimpleName(), this);}@Overridepublic 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 {@Overridepublic 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;}@Overridepublic boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {System.out.printf("%-85s:%s{%s}%n", "------BookProxyInstantiationAwareBeanPostProcessor#postProcessAfterInstantiation", bean.getClass().getSimpleName(), bean);return true;}@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.printf("%-85s:%s{%s}%n", "------BookProxyInstantiationAwareBeanPostProcessor#postProcessBeforeInitialization", bean.getClass().getSimpleName(), bean);return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.printf("%-85s:%s{%s}%n", "------BookProxyInstantiationAwareBeanPostProcessor#postProcessAfterInitialization", bean.getClass().getSimpleName(), bean);return bean;}@Overridepublic 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
,将Book
与Pen
的customInit()
添加到BeanDefinition
中,并设置Pen
的MutablePropertyValues
用于初始化后的属性装配。
同时将BookProxyInstantiationAwareBeanPostProcessor
注册到容器中。
public static void main(String[] args) {GenericApplicationContext context = new GenericApplicationContext();//注册Book的BeanDefinitionGenericBeanDefinition bookBeanDefinition = new GenericBeanDefinition();bookBeanDefinition.setBeanClass(Book.class);bookBeanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON);//指定为单例模式bookBeanDefinition.setInitMethodName("customInit");//设置初始化方法context.registerBeanDefinition("book", bookBeanDefinition);//注册Pen的BeanDefinitionGenericBeanDefinition 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();@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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的BeanDefinitionGenericBeanDefinition bookBeanDefinition = new GenericBeanDefinition();bookBeanDefinition.setBeanClass(Book.class);bookBeanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON);//指定为单例模式bookBeanDefinition.setInitMethodName("customInit");//设置初始化方法context.registerBeanDefinition("book", bookBeanDefinition);//注册Pen的BeanDefinitionGenericBeanDefinition 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);}@Overridepublic String toString() {return "Book{" +"name='" + name + '\'' +", author='" + author + '\'' +'}';}@Overridepublic 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;}@Overridepublic 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);}@Overridepublic void afterPropertiesSet() throws Exception {System.out.printf("%-85s:%s{%s}%n", COUNT.addAndGet(1) + "------Pen#afterPropertiesSet", this.getClass().getSimpleName(), this);}}
}
执行结果
从执行结果即可反应出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()
然后调用AbstractApplicationContext
所持有的实际BeanFactory
(DefaultListableBeanFactory
)句柄的preInstantiateSingletons()
做Bean容器的初始化工作。
org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
:
bean的创建流程:getBean()->doGetBean()->createBean()->doCreateBean()
我们直接定位到createBean()
从上面的流程可以看出,当执行了resolveBeforeInstantiation(beanName,mbdToUse)
方法后,有返回bean
对象,则直接return
出去了。
如果没有返回bean
对象,则会执行doCreateBean()
进行真正的常规创建流程。
在本文章的例子中,初始化book
对象的流程中BookProxyInstantiationAwareBeanPostProcessor
的postProcessBeforeInstantiation()
返回了book
的代理对象,所以在上面的流程中,直接返回出去了,没有执行doCreateBean()
方法。
接下进入resolveBeforeInstantiation(beanName,mbdToUse)
:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
createBean()
将对象返回出去,一路回到getSingleton()
:
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory<?>)
可以看到此时,已经将一个经过了InstantiationAwareBeanPostProcessor
处理的Bean
对象注册到了BeanFactory
中(在本例子里面是我们的BookProxyInstantiationAwareBeanPostProcessor
创建的Book
对象的代理类)。
经过以上流程可以看出,当InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation()
如果返回了对象的话,那么Bean
的创建流程将会直接结束返回该对象。
接下来讲InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation()
不返回对象的Bean
创建流程,在该例子里面是Pen
的创建流程:
上面的流程中,由于执行了BookProxyInstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation()
没有返回对象,所以会执行后面的doCreateBean()
来创建对象。
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
在上面的流程中,先通过反射创建了对象,然后调用populateBean()
进行属性装配,属性装配后,执行Bean的初始化流程,包含了BeanPostProcessor
的前后置处理、init-method
相关处理。
我们知道,在InstantiationAwareBeanPostProcessor
中目前还只执行了postProcessBeforeInstantiation()
,还有剩下postProcessAfterInstantiation()
、postProcessProperties()
、postProcessBeforeInitialization()
、postProcessAfterInitialization()
没有执行。
我们先看populateBean()
中的逻辑:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean
从上面的流程可以看出,populateBean()
的流程是先调用InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation()
,然后调用其InstantiationAwareBeanPostProcessor#postProcessPropertyValues()
,最后进行属性的装配工作。
此时和我们前面描述的执行流程保持一致。
接下来是postProcessBeforeInitialization()
、postProcessAfterInitialization()
的执行还没有做。
返回到上层
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)
:
从上面的initializeBean()
的流程可以看到我们首先调用了BeanPostProcessor#postProcessBeforeInitialization()
,然后执行了invokeInitMethods()
来处理bean的实现的InitializingBean
接口的afterPropertiesSet()
与自定义init-method
;最后执行BeanPostProcessor#postProcessAfterInitialization()
;
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeInitMethods
从上面的invokeInitMethods()
可以看到包含了InitializingBean
接口的处理与init-method
的方法处理流程;
init-method
方法最终会通过反射执行。
最后就是BeanPostProcessor#postProcessAfterInitialization()
方法的执行:
至此,所有的InstantiationAwareBeanPostProcessor
接口涉及到的流程都执行完毕,与前面讲述的流程一样,最后就是返回到getSingleton()
将最后最终的对象注册到容器中。
总结
以上通过围绕InstantiationAwareBeanPostProcessor
创建一个对指定Bean
对象的代理对象,对其特定方法进行代理增强的例子,来介绍了InstantiationAwareBeanPostProcessor
的应用,以及描述了InstantiationAwareBeanPostProcessor
的"短路"会控制到后续常规Bean
的创建流程。
同时,通过对源码的浅析来对InstantiationAwareBeanPostProcessor
的执行前后流程进行了讲解。
Spring之Bean后处理器——InstantiationAwareBeanPostProcessor的使用与源码解析相关推荐
- Spring 注解面面通 之 @CrossOrigin 处理请求源码解析
@CrossOrigin源码解析主要分为两个阶段: ① @CrossOrigin注释的方法扫描注册. ② 请求匹配@CrossOrigin注释的方法. 本文针对第②阶段从源码角度进行解 ...
- Spring的Autowired自动装配(XML版本+Annotation版本+源码+解析)
http://moshowgame.iteye.com/blog/1607718 @Autowired自动装配 上面的例子我们用的都是手动装配的,如果DAO-Service一多那就很麻烦了,那么我们需 ...
- Spring 注解面面通 之 @CrossOrigin 注册处理方法源码解析
参照<Spring 注解面面通 之 @RequestMapping 注册处理方法源码解析>,其讲解了@RequestMapping注释的处理方法注册过程,而@CrossOrigin是基 ...
- 品Spring:详细解说bean后处理器
一个小小的里程碑 首先感谢能看到本文的朋友,感谢你的一路陪伴. 如果每篇都认真看的话,会发现本系列以bean定义作为切入点,先是详细解说了什么是bean定义,接着又强调了bean定义为什么如此重要. ...
- Spring MVC源码解析——HandlerMapping(处理器映射器)
Sping MVC 源码解析--HandlerMapping处理器映射器 1. 什么是HandlerMapping 2. HandlerMapping 2.1 HandlerMapping初始化 2. ...
- Spring Bean的生命周期以及IOC源码解析
IOC源码这一块太多只能讲个大概吧,建议还是去买本Spring IOC源码解析的书来看比较好,我也是自己看源代码以及视频整理的笔记 Bean的生命周期大概可以分为四个阶段,具体的等会再说,先看看IOC ...
- Spring源码解析-bean实例化
Spring源码解析-bean实例化 本文介绍Spring创建 bean 过程中的第一个步骤:实例化 bean. 1. Bean实例化源码 虽然实例化Bean有多种方式(包括静态工厂和工厂实例 ...
- Spring源码解析(五)-Bean的实例化流程(上)
在前面已经完成了对需要实例化bean的收集并封装成BeanDefinition,并且将BeanPostProcess等组件进行了提前实例化.接下来就到了容器启动的最后一步,也是最复杂的一步-实例化be ...
- Spring源码解析(七)-Bean属性间的循环依赖
首先复习一下前面学习的Spring容器启动的大致流程,首先Spring会先扫描所有需要实例化的Bean,将这些Bean的信息封装成一个个BeanDefinition,然后注册到BeanDefiniti ...
- Spring 源码解析 - Bean创建过程 以及 解决循环依赖
一.Spring Bean创建过程以及循环依赖 上篇文章对 Spring Bean资源的加载注册过程进行了源码梳理和解析,我们可以得到结论,资源文件中的 bean 定义信息,被组装成了 BeanDef ...
最新文章
- 企业微信发送企业红包java_发放企业红包
- 结构光双目视觉测距原理
- Objections vs. excuses
- TCP/IP中的传输层协议TCP、UDP
- JavaScript刷新页面,不重复提交
- bat 调用class文件_[Golang实现JVM第五篇]静态方法调用的实现
- MyBatis学习02
- 将点分十进制转换为ip地址表示
- 管道无损检测python_初用python-docx
- 1206_MISRA_C规范学习笔记_Rule 10.1 Rule 10.2
- windows计算机日志时间id6008,windows错误事件id6008修复方法
- 思科服务器dns配置文件,cisco设置dns方法
- AUTOSAR-基本概念
- matlab for循环与subs应用 求解
- 日拱一卒无有尽,功不唐捐终入海
- 12点转成0点(原因时间格式化为十二小时制导致)
- 12035徐波:PMBOK融会贯通:会议一览
- java 队列线程池_JAVA工作队列与线程池
- 手机端设置缩放的解决方法和遇到的UC浏览器的坑
- 怀旧服小号最多的服务器,怀旧服入坑攻略:10个快速练级技巧要领
热门文章
- 无线射频收发芯片SI24R1技术相关问题解答
- Python面向对象加强2.Python 中类的内置属性和内置方法(魔法函数)
- python编程一球从100米_Python求解一个球从100米高度自由落下的问题
- ajax批量上传数据,Ajax上传数据和上传文件(三种方式)
- 2020年大学生编程比赛---ACM、蓝桥杯、天梯赛
- nssa和stub_Stub区域和NSSA区域比较
- java使用代理请求https
- python爬数据实例_Python实例教程爬虫爬取NBA数据功能示例
- UWP开发入门(八)——聊天窗口和ItemTemplateSelector
- 将鼠标放在A标签上时浏览器左下角会显示跳转后界面地址,如何隐藏