引言
词语解释
BeanDefinition #(后面简称BD) spring当中用来描述bean的一个接口,包括作用域,属性值,构造函数等信息。通过它就可以完成一个bean的实例化
BeanDefinitionHolder #对BeanDefinition做了一次封装
BeanDefinitionRegistry #用来管理BeanDefinition,提供了向容器注册,删除,获取BeanDefinition对象的方法
AnnotatedBeanDefinitionReader #读取一个被加了注解的类,转成BeanDefinition
ClassPathBeanDefinitionScanner #扫描制定包下的类,并且转换成BeanDefinition
BeanPostProcessor #后置处理器,在Bean初始化前后会回调它的两个方法,(可以插手干预Bean实例化过程,在init()前后执行,对所有bean进行处理)
BeanFactoryPostProcessor #后置处理器 容器级别的后置处理器 可以对BeanDefinition进行修改。相比BeanPostProcessor触发更靠前,处理级别更高
开始
1.先看下最基本的启动 Spring 容器的例子:(基于spring 5.0.x)
public static void main(String[] args) {
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(Appconfig.class);
annotationConfigApplicationContext.getBean(IndexService.class);
}
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
//把配置类注册到容器中(配置类-> BeanDefinition-> 放到BeanDefinition Map 这个map可以暂时狭隘的理解为ioc容器)
register(annotatedClasses);
//刷新上下文 容器启动核心方法
refresh();
}
※注意 this()中初始化了AnnotatedBeanDefinitionReader,这个类也比较重要,里面定义了很多BeanPostProcessor(上面名词解释有),我们常用的注解@Autowired等 都依赖这里创建的各种BeanPostProcessor
2.register()方法重点完成了对配置类本身的解析和注册
方法中主要实现了下面几个逻辑,具体代码就不放了,需要详细注释的可以留言
1.根据指定的bean创建一个AnnotatedGenericBeanDefinition(继承自
BeanDefinition)
2.解析bean作用域,如果有@Scope注解,则解析@Scope,没有则默认为singleton,将作用域回写到bd中
3.处理通用注解(主要处理 Lazy DependsOn Primary Role 等)处理完成后回写到bd中
4.生成definitionHolder(其实就是封装了beanName和bd)
5.将bean注册到容器中(可狭隘的理解为将bd放到了beanDefinitionMap中)
3.refresh()刷新上下文
refresh()方法的作用加载或者刷新当前的配置信息,如果已经存在spring容器,则先销毁之前的容器,重新创建spring容器,载入bean定义,完成容器初始化工作。refesh()方法及功能如下:
具体分析refresh中的函数逻辑:
1.刷新预处理:prepareRefresh()
AbstractApplicationContext. prepareRefresh ()方法
protected void prepareRefresh() {
//设置容器启动时间
this.startupDate = System.currentTimeMillis();
//是否激活标识位
this.closed.set(false);
this.active.set(true);
if (logger.isInfoEnabled()) {
logger.info("Refreshing " + this);
}
//空方法,可能用于后期扩展
initPropertySources();
//校验属性的合法性等
getEnvironment().validateRequiredProperties();
this.earlyApplicationEvents = new LinkedHashSet<>();
}
2.获取bean工厂:obtainFreshBeanFactory()
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
/**
这个方法在不同的实现容器中有区别,
如果是xml方式配置,会使用AbstractRefreshableApplicationContext中的实现,并且解析xml配置文件转成beanDefinition
如果是注解方式,并没有解析包下的注解,而是通过第5步(invokeBeanFactoryPostProcessors())执行的后置处理器完成对bean的加载
这里我们用的是注解的方式启动所以这里只返回一个bean工厂
**/
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
3.准备bean工厂:prepareBeanFactory()
prepareBeanFactory主要完成beanFactory的一些属性设置
4.postProcessBeanFactory() 空方法 可能后期扩展
5.执行bean工厂后置处理器: invokeBeanFactoryPostProcessors()
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
/**
* invokeBeanFactoryPostProcessors内部维护了List<BeanFactoryPostProcessor>,List<BeanDefinitionRegistryPostProcessor>
* 先执行实现了BeanDefinitionRegistryPostProcessor接口的PostProcessor,按优先级执行
* 再执行实现了BeanFactoryPostProcessor接口的postProcessor
*
* 在处理BeanDefinitionRegistryPostProcessor的时候有一个非常重要的过程:
* 在AnnotationConfigApplicationContext构造函数中初始化reader(AnnotatedBeanDefinitionReader)时 添加了一个spring自己的ConfigurationClassPostProcessor组件
* ConfigurationClassPostProcessor这个组件在这里执行用来处理添加@Configuration注解的类,并将Bean定义注册到BeanFactory中。
* 到这里加了@Configuration和加了@Bean和@ComponentScan("com.test")包下的bean被放到了容器中
* 里面的代码太多就不展开了
**/
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
6.注册BeanPostProcessor,拦截bean初始化过程:registerBeanPostProcessors()
大致逻辑是:
1.获取所有的beanPostProcessor
2.根据接口类型分出4种后置处理器类型(PriorityOrdered,Order, MergedBeanDefinitionPostProcessor, 普通类型)
3.依次注册到容器中
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 获取BeanFactory中注册的类型为BeanPostProcessor.class的bean名称。一般获取到的是实现了BeanPostProcessor接口的Bean
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// 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));
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
//按优先级分类
// 将BeanPostProcessors分为实现了PriorityOrdered,Ordered等类型
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)) {
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);
}
}
priorityOrderedPostProcessors.remove(1);
// First, register the BeanPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
//先注册实现PriorityOrdered接口的处理器,添加到beanfactory容器中
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
// 然后,注册实现了Ordered的BeanPostProcessors
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.
// 现在注册所有常规的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.
internalPostProcessors.remove(1);
//最后,重新注册所有internal BeanPostProcessors(实现MergedBeanDefinitionPostProcessor接口的后置处理器)
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
//注册ApplicationListenerDetector,用于Bean创建完时检查是否是ApplicationListener
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
7.初始化所有剩下的单例bean,单例bean在初始化容器时创建,原型bean在getbean()时创建
DefaultListableBeanFactory. preInstantiateSingletons()
public void preInstantiateSingletons() throws BeansException {
if (logger.isDebugEnabled()) {
logger.debug("Pre-instantiating singletons in " + this);
}
//获取容器中所有bean的名字
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
// 触发所有非延迟加载单例beans的初始化,主要步骤为调用getBean
for (String beanName : beanNames) {
//获取BeanDefinition 合并父 Bean 中的配置,<bean id="" class="" parent="" /> 中的 parent
//类似继承 继承父bean的信息,也可以覆盖一些信息,也可以增加一些信息
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
//非抽象,单例,非延时加载的
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//是不是factoryBean
if (isFactoryBean(beanName)) {
//如果是FactoryBean则加上& FactoryBean(会返回两个对象 一个是getObject中返回的 一个是他自己 &+beanName)
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
//对于普通的 Bean,只要调用 getBean(beanName) 这个方法就可以进行初始化了
getBean(beanName);
}
}
}
// 到这里说明所有的非懒加载的 单例 bean 已经完成了初始化
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
8.finishRefresh()完成BeanFactory的初始化创建工作,IOC容器就创建完成
protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
//1. 初始化生命周期有关的后置处理器,BeanFactory创建完成后刷新相关的工作
//默认从容器中找是否有lifecycleProcessor的组件【LifecycleProcessor】;如果没有new DefaultLifecycleProcessor();加入到容器;
clearResourceCaches();
// Initialize lifecycle processor for this context.
//1. 初始化生命周期有关的后置处理器,BeanFactory创建完成后刷新相关的工作
//默认从容器中找是否有lifecycleProcessor的组件【LifecycleProcessor】;如果没有new DefaultLifecycleProcessor();加入到容器;
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
//2. 拿到前面定义的生命周期处理器(LifecycleProcessor);回调onRefresh();
getLifecycleProcessor().onRefresh();
// Publish the final event.
//3. 发布容器刷新完成事件;
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}
结尾
以上基本大致分析了AnnotationConfigApplicationContext容器的初始化过程,容器启动过程中会先保存bean定义信息,然后容器根据条件创建bean实例,创建实例后会使用多种后置处理器增强bean的功能,比如处理aop等。
简单来说就是分为两部分 一个是将配置转化成BeanDefinition然后注册到容器中(就是放到了map中) 第二是将map中的bean初始化(单例的在启动初始化,原型在getBean初始化)。