目录
3.5 初始化非延迟加载的的单例Bean (延迟加载的单例将在第一次调用的时候初始化)
使用示例:
AnnotationConfigApplicationContext annotationConfigApplicationContext =new AnnotationConfigApplicationContext(AppConfig.class);
UserService userService = (UserService) annotationConfigApplicationContext.getBean("userService");
userService.query();
分析:
- 构建AnnotationConfigApplicationContext实例
- 调用getBean方法获取Bean
- 执行目标bean的方法
AnnotationConfigApplicationContext#AnnotationConfigApplicationContext实现:
/**
* 这个构造方法需要传入一个被javaconfig注解了的配置类
* 然后会把这个被注解了javaconfig的类通过注解读取器读取后继而解析
*/
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
/**
* 1. 初始化上下文环境 --> 完成了Spring内部定义的BeanFactory后处理器的注册
* 2. 初始化注解bean定义解析器和类路径bean定义扫描器
*/
this();
/**
* 程序执行到这步之前, Spring内部的BeanDefinition(BeanFactory后处理器)已经注册到beanFactory中;
* 该步骤只是将手动提供的annotatedClasses(配置类)也注册到beanFactory中;
* 其他的注解bean还没有被注册, 整个注册过程刚刚开始
* 其他的注解bean是在激活后处理器中的方法时, 对配置类进行解析, 解析到@ComponentScan注解中的包路径后才进行解析注册
*/
register(annotatedClasses);
//环境刷新
refresh();
}
分析:
- 初始化上下文环境; 完成了Spring内部定义的BeanFactory后处理器的注册, 初始化注解bean定义解析器和类路径bean定义扫描器
- 程序执行到这步之前, Spring内部的BeanDefinition(BeanFactory后处理器)已经注册到beanFactory中; 该步骤只是将手动提供的annotatedClasses(配置类)也注册到beanFactory中; 其他的注解bean还没有被注册, 整个注册过程刚刚开始其他的注解bean是在激活后处理器中的方法时, 对配置类进行解析, 解析到@ComponentScan注解中的包路径后才进行解析注册
- 应用环境刷新
1. 注册内部处理器类
_1. AnnotationConfigApplicationContext#AnnotationConfigApplicationContext实现:
/**
* 初始化一个bean的读取和扫描器
* 何谓读取器和扫描器参考上面的属性注释
* 默认构造函数,如果直接调用这个默认构造方法,需要在稍后通过调用其register()
* 去注册配置类(javaconfig),并调用refresh()方法刷新容器,
* 触发容器对注解Bean的载入、解析和注册过程
* 这种使用过程我在ioc应用的第二节课讲@profile的时候讲过
*
* 注意在初始化AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner时需要传递的是bean定义注册器用来存储解析好的bean定义信息
* AnnotationConfigApplicationContext实现了GenericApplicationContext,而GenericApplicationContext实现了BeanDefinitionRegistry接口
*/
public AnnotationConfigApplicationContext() {
/**
* 实例化注解bean的解析器, 并会对beanFactory进行一些初始化配置
*/
this.reader = new AnnotatedBeanDefinitionReader(this);
/**
* ClassPathBeanDefinitionScanner: 可以用来扫描包或者类,继而转换成bd
* 1.当初始化AnnotationConfigApplicationContext时传入的是配置类的Class信息时
* 在后面根据注解信息获取到包信息并扫描时使用的并不是这个scanner对象, 而是spring内部实例化的一个ClassPathBeanDefinitionScanner
* {@link ComponentScanAnnotationParser#parse(org.springframework.core.annotation.AnnotationAttributes, java.lang.String)}
* 2.当初始化AnnotationConfigApplicationContext时传入的是配置类的包路径信息时
* 在{@link this#scan(String...)}方法中对包路径进行扫描时使用的是该scanner对象
*
* 总之: 两种方式对包的扫描工作都是在{@link ClassPathBeanDefinitionScanner#doScan(String...)}中进行的
*/
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
分析:
- 实例化注解bean的解析器, 并会对beanFactory进行一些初始化配置, 其中就包括处理器类的注册
- 实例化类路径扫描器,可以用来扫描包信息,对该包路径下的Bean进行解析
注意:
- 当初始化AnnotationConfigApplicationContext时传入的是配置类的Class信息时在后面根据注解信息获取到包信息并扫描时使用的并不是这个scanner对象, 而是spring内部实例化的一个ClassPathBeanDefinitionScanner
- 当初始化AnnotationConfigApplicationContext时传入的包路径信息时, 在{@link this#scan(String...)}方法中对包路径进行扫描时使用的是该scanner对象
_1. AnnotatedBeanDefinitionReader#AnnotatedBeanDefinitionReader实现:
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
. . .
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
/**
* 设置beanFactory中的DependencyComparator和AutowireCandidateResolver属性
* 注册一些beanFactory内部的注解配置处理器类
*/
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
分析: 将注册中心维护在AnnotatedBeanDefinitionReader中以及注册一些BeanFactory内部的注解配置处理器类
AnnotationConfigUtils#registerAnnotationConfigProcessors实现:
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
/**
* 1. 对beanFactory的属性进行设置
*/
//获取注册器中维护的DefaultListableBeanFactory工厂
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
//如果beanFactory不为空, 则设置beanFactory的DependencyComparator和AutowireCandidateResolver属性
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
//AnnotationAwareOrderComparator主要能解析@Order注解和@Priority
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
//ContextAnnotationAutowireCandidateResolver提供处理延迟加载的功能
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
/**
* 2. 注册Spring内部的处理器类(实现BeanDefinitionRegistryPostProcessor接口和BeanFactoryPostProcessor接口)
* Spring在内部类维护这些类, 为BeanFactory提供特定的功能
* 以下7个类是最先注册到beanFactory中的BeanDefinitionMap集合中去
* (1).org.springframework.context.annotation.internalConfigurationAnnotationProcessor -->只有这一个实现了BeanDefinitionRegistryPostProcessor接口
* (2).org.springframework.context.annotation.internalAutowiredAnnotationProcessor
* (3).org.springframework.context.annotation.internalRequiredAnnotationProcessor
* (4).org.springframework.context.annotation.internalCommonAnnotationProcessor
* (5).org.springframework.context.annotation.internalPersistenceAnnotationProcessor -->这个没有被注册
* (6).org.springframework.context.event.internalEventListenerProcessor
* (7).org.springframework.context.event.internalEventListenerFactory
*/
//暂存BeanDefinitionHolder的Set集合
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
//判断注册器中是否含有指定的BeanDefinition,并注册到到注册器中, 然后将beanName和BeanDefinition封装到BeanDefinitionHolder
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
//需要注意的是ConfigurationClassPostProcessor的类型是BeanDefinitionRegistryPostProcessor
//而 BeanDefinitionRegistryPostProcessor 最终实现BeanFactoryPostProcessor这个接口
//根据spring内部提供的class实例化ConfigurationClassPostProcessor
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
//AutowiredAnnotationBeanPostProcessor 实现了 MergedBeanDefinitionPostProcessor
//MergedBeanDefinitionPostProcessor 最终实现了 BeanPostProcessor
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
/**
* 注册后处理器类
*/
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 检查JPA支持,如果存在,添加PersistenceAnnotationBeanPostProcessor
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}
/**
* 3. 将注册Spring内部的类封装到Set集合中返回
*/
return beanDefs;
}
分析:
1. 对beanFactory的属性进行设置
2. 注册Spring内部的处理器类(实现BeanDefinitionRegistryPostProcessor接口和BeanFactoryPostProcessor接口), Spring在内部类维护这些类, 为BeanFactory提供特定的功能
以下7个类是最先注册到beanFactory中的BeanDefinitionMap集合中去
(1). org.springframework.context.annotation.internalConfigurationAnnotationProcessor (重点)
(2). org.springframework.context.annotation.internalAutowiredAnnotationProcessor
(3). org.springframework.context.annotation.internalRequiredAnnotationProcessor
(4). org.springframework.context.annotation.internalCommonAnnotationProcessor
(5). org.springframework.context.annotation.internalPersistenceAnnotationProcessor
(6). org.springframework.context.event.internalEventListenerProcessor
(7). org.springframework.context.event.internalEventListenerFactory
3. 将注册Spring内部的类封装到Set集合中返回
_2. AnnotationConfigUtils#registerPostProcessor实现:
private static BeanDefinitionHolder registerPostProcessor(BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(beanName, definition);
return new BeanDefinitionHolder(definition, beanName);
}
GenericApplicationContext#registerBeanDefinition ==> DefaultListableBeanFactory#registerBeanDefinition实现:
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {
. . .
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
/**
* 注册前的最后一次校验,这里的校验不同于之前的XML文件校验
* 主要是对于AbstracBeanDefinition属性中的methodOverrides校验,
* 校验methodOverrides是否与工厂方法并存或者methodOverrides对应的方法不存在
*/
((AbstractBeanDefinition) beanDefinition).validate();
}
. . .
}
//判断该beanName是否已经注册 ,根据不同的设置记性处理; (不愧是Spring, 在我模拟的SpringIOC中我管它那么多, 直接覆盖 ,简单粗暴)
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
//如果对应的BeanName已经注册且在配置中配置了bean不允许被覆盖,则抛出异常
. . .
//注册beanDefinition(将beanDefinition放入map缓存中)
this.beanDefinitionMap.put(beanName, beanDefinition);
}
//处理注册未被注册的beanName的情况
else {
/**
* 检查这个工厂的bean创建阶段是否已经开始,即 是否有任何bean被标记为同时创建。
* 如果bean工厂的bean创建已经开始, 那么就不能在beanDefinitionNames集合中添加beanName; 因为创建bean时, 会迭代beanDefinitionNames集合,获取beanName,获取BeanDefinition创建bean实例
* 一旦开始迭代, 则不允许在向该map集合中插入元素
*/
if (hasBeanCreationStarted()) {
//处于bean创建阶段
//因为beanDefinitionMap是全局变量,这里肯定会存在并发访问的情况
synchronized (this.beanDefinitionMap) {
//注册beanDefinitionv
this.beanDefinitionMap.put(beanName, beanDefinition);
//创建新的集合来更新存储已注册beanName的beanDefinitionNames集合
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
//更新manualSingletonNames(存储单例bean)集合
if (this.manualSingletonNames.contains(beanName)) {
Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
updatedSingletons.remove(beanName);
this.manualSingletonNames = updatedSingletons;
}
}
}
//仍处于注册阶段
else {
//将beanName和bean的定义信息加入beanDefinitionMap集合
this.beanDefinitionMap.put(beanName, beanDefinition);
//bean定义名称列表,按注册顺序排列
this.beanDefinitionNames.add(beanName);
//手动注册的单例程序的名称列表,按注册顺序排列
this.manualSingletonNames.remove(beanName);
}
this.frozenBeanDefinitionNames = null;
}
//如果该bean定义已经注册,并且为单例,则进行重置
if (existingDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
}
分析:
- 注册前的最后一次校验,这里的校验不同于之前的XML文件校验, 主要是对于AbstracBeanDefinition属性中的methodOverrides校验, 校验methodOverrides是否与工厂方法并存或者methodOverrides对应的方法不存在
- 判断该beanName是否已经注册; 如果beanName已经注册过: 根据不同的设置进行处理(是否允许覆盖, 如果不允许,则抛出异常; 允许的话, 则进行注册)
- 如果beanName没有被注册过; 则开始检查这个工厂的bean创建阶段是否已经开始,即是否有任何bean被标记为同时创建。如果bean工厂的bean创建已经开始, 那么就不能在beanDefinitionNames集合中添加beanName; 因为创建bean时, 会迭代beanDefinitionNames集合, 获取beanName, 获取BeanDefinition创建bean实例; 一旦开始迭代, 则不允许在向该list集合中插入元素, 但是beanDefinitionMap集合可以, 因为beanDefinitionMap集合并没有被迭代, 而是通过beanName获取BeanDefinition信息;
- 如果该bean定义已经注册, 并且为单例, 则进行重置
2. 注册Java配置类
AnnotationConfigApplicationContext#register实现:
public void register(Class<?>... annotatedClasses) {
...
this.reader.register(annotatedClasses);
}
分析: 通过读取器AnnotatedBeanDefinitionReader的register()方法, 去读取配置类的信息, 并进行注册;
AnnotatedBeanDefinitionReader#register
==> AnnotatedBeanDefinitionReader#registerBean
==> AnnotatedBeanDefinitionReader#doRegisterBean实现:
<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
//封装注解bean的定义信息
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
//设置InstanceSupplier属性
abd.setInstanceSupplier(instanceSupplier);
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
//设置bean的模式, 默认为单例模式
abd.setScope(scopeMetadata.getScopeName());
//获取beanName
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
//处理普通的bean定义注解 对@Lazy,@Primary,@DependsOn @Description @Role等标签的解析
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
if (qualifiers != null) {
for (Class<? extends Annotation> qualifier : qualifiers) {
if (Primary.class == qualifier) {
abd.setPrimary(true);
}
else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
}
else {
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
customizer.customize(abd);
}
//将AnnotatedGenericBeanDefinition(bean定义信息)和beanName封装到BeanDefinitionHolder中
// //目的: 封装更多的bean定义信息(bean定义信息, 别名信息, beanName等), 将bean定义信息与be