spring体系结构特别繁琐,其中最核心的就是ioc和aop。
首先了解如何基于注解启动spring容器。
注解方式环境搭建
@Configuration
使用Configuration 配置容器
@Configuration |
public class UserEntity { |
使用注解形式形式加载IOC
private static AnnotationConfigApplicationContext applicationContext; |
AnnotationConfigApplicationContext是继承于ApplicationContext,专门为注解方式的spring上下文加载控制器。spring boot就是用的这个控制器实现的。
比较老旧的读取xml的ApplicationContext是ClassPathXmlApplicationContext。
先来看看new AnnotationConfigApplicationContext(MySpringConfig.class);的内部调用
最后会走入
AnnotatedBeanDefinitionReader.doRegisterBean方法
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);方法我们来看看
方法调用者的this.registry是啥呢?
方法调用者的构造方法
发现没有 这个 this.registry就是AnnotationConfigApplicationContext
AnnotationConfigApplicationContext的父级GenericApplicationContext就实现了registerBeanDefinition方法,又调用了内部的beanfactory
Beanfactory对象是DefaultListableBeanFactory
让我们看看DefaultListableBeanFactory,发现这个就是真正的beanfactory容器!!里面的
beanDefinitionMap就是专门根据id储存bean对象的
这样一来spring的配置信息终于读取完成,并且注册到bean容器了。
接下来看其他的bean是怎么注册的吧
查看
public AnnotationConfigApplicationContext(Class... annotatedClasses) {
this();
this.register(annotatedClasses);
this.refresh();
}
的refresh方法
refresh又调用了finishBeanFactoryInitialization,继续调用的preInstantiateSingletons方法.再继续调用getbean继续一个劲的往下找 最后终于找到生成bean的地点 docreatebean 。
根据方法名可以才看出来是会初始化非懒加载的,并且作用域是单例的bean对象。
继续往下之前 我们需要了解一下BeanPostProcessor,Aware和InitializingBean接口。
AWARE接口是属于获取bean上下文的一种接口 ,具体实现类有很多,比如ApplicationContextAware,beanfactoryaware,他会在执行完构造函数之后执行
BeanPostProcessor接口是前置后置处理器,主要作用是再初始化bean的时候,环绕bean的初始化方法(不是构造方法,bean在走完钩爪方法后还会有一个bean初始化方法,这个方法需要开发人员根据业务需求去编写,如果没有这个需求,就不会有bean初始化方法)。
想要编写bean初始化方法 需要继承InitializingBean接口
代码示例 代码执行顺序是重上往下
这个时候是不是瞬间发现了bean的生命周期
spring的生命周期就是
-》构造方法
-》反向注入需要的bean对象
-》执行aware (这里需要注意,很多aware也是基于BeanPostProcessor实现的方法调用的,所以他也可能处于bean初始化的前置环绕或者后置环绕)
-》执行bean初始化前置环绕(ApplicationContextAware就是通过前置处理器实现的)
-》执行bean初始化方法
-》执行bean初始化后置环绕(aop的动态代理就是在这儿实现的,aop就是后置处理器的aware实现的)
-》bean销毁
我们了解这些后 我们继续看看源码的AbstractAutowireCapableBeanFactory下的docreatebean方法
进入initializeBean方法
继续深入invokeAwareMethods就可以看到只有BeanNameAware,BeanClassLoaderAware和BeanFactoryAware这几个Aware
是在这儿执行的。说明其他的aware都是基于BeanPostProcessor实现的
嗯 springioc源码基本到这儿就讲解完了 ,在这儿补充一个流程图