初始化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