Spring源码解析 Spring Bean生命周期

128 阅读2分钟

初始化Spring的环境,通过Javaconfig技术依赖appConfig配置类扫描配置下的指定路径包

AnnotationConfigApplicationContext  注解配置应用程序上下文

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Appconfig.java);

这一行代码表示把Spring所有前提环境准备好

准备好什么

  • 把bean工厂准备好
  • 把bean的IOC容器准备好
  • 类都被实例化

进入这个类看到

因为这个类有个父类,所以先调用父类的构造方法

AnnotatedBeanDefinitionReader reader;

这个类顾名思义就是一个reader读取器,读取什么

AnnoationBeanDefintition意思是被加了注解的bean

这个类是在构造方法中实例化的

这个reader我们先认为有了这个读取器就可以读取被加注解的bean

ClassPathBeanDefinitionScanner(this);

这个Scanner用来做扫描的

继续执行****register方法

为什么之前要实例化reader读取器

因为需要在这里面调用register方法

之前演示过一个问题把Appcofig中的**@ComponentScan**

去掉,运行项目就会报错,为什么会报错,因为Spring 容器中根本就没有这个IndexDao.query,根本就没有扫描

但是可以注册单个类

注意的是必须要refresh一下,不然会报错

进入register调用registerBean

注册单个bean给容器
比如有新加的类可以用这个方法
但是去注册注册之后需要手动调用refresh方法去解析注解

有两个意思
1.注册配置类
2.单独注册一个bean


AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);

根据制定的bean创建一个AnnotationGenericBeanDefintition

这个AnnotationGenericBeanDefintition可以理解为一个数据结构

AnnotationGenericBeanDefintition包含了其它信息,比如元信息,lazy,scope

if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {   
return;
}

判断这个类是否跳过解析,通过代码可以看出Spring判断这个类是否需要跳过解析主要判断是否添加注解

//得到类的作用域
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
//把类的作用域添加到数据结构中
abd.setScope(scopeMetadata.getScopeName());

//生成类的名字
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

/** * 处理类当中的通用注解 * 分析源码可以知道主要处理 * 
Lazy Primary DependsOn Description Role等注解 * 
处理完成之后processCommonDefinitionAnnotations依然是把他添加到数据结构中 */
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);

/** * TODO BeanDefinitionHolder也是一个数据结构 *      
为什么使用BeanDefinitionHolder *      
BeanDefinitionHolder是beanDefinition的封装 *      
进入BeanDefinitionHolder可以看出里面封装了 *      
.BeanDefinition对象 *      
2.beanName bean名称 *      
3.aliases 别名 *   
因为注册beanDefinition需要参数有很多,为了方便传参,简化,封装了一个对象 */
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);

BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);

把bd注册到容器中

// Still in startup registration phase
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
this.manualSingletonNames.remove(beanName);

this 就是DefaultListableBeanFactory