学java必学spring,java程序员就是spring程序员,spring作为java开发的基础设施(infrastructure),在大多数java程序员看来最重要的功能就是IOC和AOP,实际上spring最重要的功能是它提供的各种扩展点,方便我们整合其它框架,今天来聊聊spring创建bean的过程中各种扩展接口的调用
话不多说,先上一张我在看源码过程中画的流程图,大家可以先看看有个总体印象。
流程图在线查看地址:
https://www.processon.com/view/link/615c4965f346fb69a724dc8c
Bean创建过程扩展点详解:
扩展点一:
InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
这是实例化之前第一次调用Bean后置处理器,它的主要设计目的就是在实例化之前我们可以按照我们自己的逻辑创建任意的对象(一般是代理对象),如果这一步返回的对象不为空,则直接返回我们自己创建的对象,不会走剩下的创建流程,代码如下图:
扩展点二:
SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors
这是实例化之前的第二次调用,用来推断调用哪个构造器来实例化我们的对象,这个扩展点主要提供给spring自己使用,不做过多展开,代码如下图:
扩展点三:
MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
这是实例化之后第一次调用,允许后置处理器修改合并后的BeanDefinition,比如设置初始化方法,@Autowired、@Resource和@Value注解就是在这里解析的,解析后封装到InjectionMetadata,供后面属性注入使用,代码如下图:
扩展点四:
SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference
这是实例化之后第二次调用,主要是用来处理循环依赖,会把创建的对象 放到earlySingletonObjects,代码如下图:
扩展点五:
InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
这是进入属性填充方法后执行的方法,在这里我们可以自己为bean填充属性,此方法的返回值为boolean,如果返回为false,则直接返回,不继续后面的属性注入逻辑,代码如下图:
扩展点六:
InstantiationAwareBeanPostProcessor#postProcessPropertyValues
主要是CommonAnnotationBeanPostProcessor(用来处理@Resource注解)和AutowiredAnnotationConigApplication(处理@Autowired和@Value注解);如果是自动注入(AutowireMode不为null),是无需通过后置处理器来进行属性注入的,代码如下图:
扩展点七:调用Aware接口的方法
下面是初始化阶段了,如果我们的bean实现了各种Aware接口,则spring就会调用Aware接口对应的方法,比如实现了BeanNameAware,我们可以拿到bean的名字,实现了BeanClassLoaderAware可以拿到bean的类加载器,实现了BeanFactoryAware,可以拿到bean的工厂,实现了ApplicationContextAware可以拿到应用上下文,代码如下图:
扩展点八:
BeanPostProcessor#postProcessBeforeInitialization
这里是初始化前调用后置处理器的地方,@postconstruct注解的方法就是在这里被后置处理器调用的,代码如下图:
扩展点九:
InitializingBean#afterPropertiesSet
如果我们的bean实现了InitializingBean接口,会在这里调用,工作中我经常用这个接口来进行一些初始化工作,比如布隆过滤器的初始化,微服务中网关统一认证授权时公钥的拿取,代码如下图:
扩展点十:调用用户自己注解的InitMethod
扩展点十一:
BeanPostProcessor#postProcessAfterInitialization
大名鼎鼎的AOP就是在这里生成的