SpringIOC 容器加载过程
第一步:实例化化容器:AnnotationConfigApplicationContext
@Configuration
@ComponentScan("cn.zhe")
public class MainStartTest {
public static void main(String[] args) {
// SpringIOC 出发点 加载Spring上下文
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainStartTest.class);
HelloSpring bean = applicationContext.getBean(HelloSpring.class);
bean.sayHello();
}
}
构造函数
// 根据参数可知,可以传入多个Class,但这种情况及其少见
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
/**
* 调用无参构造函数
* 主要分三步:
* a.调用父类构造函数
* b.本类构造函数 初始化注解模式下的 bean定义读取器 AnnotatedBeanDefinitionReader
* c.本类构造函数 初始化 classPath类型的 bean定义扫描器 AnnotatedBeanDefinitionScaner
*/
this();
/**
* 注册配置类
* 把传入的类进行注册,分为两种情况
* a. @Configuration的配置类
* b. 传入普通 Bean (基本不会这么做)
* Spring把配置类分为两种
* a. 带@Configuration注解的配置类称之为FULL配置类
* b. 不带@Configuration注解,是带有@Component,@Import,@ImportResouce,
* @Service, @ComponentScan等注解的配置类称之为Lite配置类
*/
register(componentClasses);
// 刷新IOC容器
refresh();
}
this()方法分析开始
第二步:实例化工厂:DefaultListableBeanFactory
DefaultListableBeanFactory 就是我们所说的容器,里面放着beanDefinitionMap, beanDefinitionNames等
// 调用无参构造,会先调用父类GenericApplicationContext的构造函数
// 第一步调用父类构造函数,创建一个Bean工厂
public GenericApplicationContext() {
/**
* 调用父类的构造函数,为 ApplicationContext spring 上下文对象初始 beanFactory
* 因为 DefaultListableBeanFactory 是最底层的实现,功能是最全的
*/
this.beanFactory = new DefaultListableBeanFactory();
}
// 第二三步
public class AnnotationConfigApplicationContext extends GenericApplicationContext
implements AnnotationConfigRegistry {
// 注解bean定义读取器,主要作用是用来读取被注解的Bean
private final AnnotatedBeanDefinitionReader reader;
// 外部调用scan手动扫描的scanner对象,用处不大
private final ClassPathBeanDefinitionScanner scanner;
public AnnotationConfigApplicationContext() {
/**
* 初始化注解模式下的bean定义扫描器
* 调用AnnotatedBeanDefinitionReader构造方法,传入的
* 是this(AnnotationConfigApplicationContext)对象
*/
this.reader = new AnnotatedBeanDefinitionReader(this);
/**
* 初始化classPath类型的bean定义扫描器
* 使用场景极少,仅外部手动调用扫描使用,常规方式是不会用到scanner对象的
* 此处扫描器仅用于自定义的扫描 applicationContext.scan();
*/
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
}
第三步:实例化 BeanDefinition 读取器 (AnnotatedBeanDefinitionReader)
主要就做了两件事情:
- 注册内置 BeanPostProcessor
- 注册内置相关核心的 BeanDefinition
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
// 把ApplicationContext对象赋值给AnnotatedBeanDefinitionReader
this.registry = registry;
// 用户处理条件表达式计算 @Condition
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
// 注册一些配置的后置处理器,并注册Spring内置的多个Bean
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
关于registerAnnotationConfigProcessors(this.registry);
方法内容较多,但大多相同的判断,注册 Spring 内置的多个 Bean,以ConfigurationClassPostProcesso
为例:
/**
* 为容器中注册解析配置类的后置处理器 ConfigurationClassPostProcessor
* org.springframework.context.annotation.internalConfigurationAnnotationProcessor
*/
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
/**
* 这方法为BeanDefinition设置了一个Role,ROLE_INFRASTRUCTURE代表这是spring内部的,并非用户定义的
* registry.registerBeanDefinition(beanName, definition);是一个接口方法,
* 实现类是 DefaultListableBeanFactory
* 核心工作就是
* a.this.beanDefinitionMap.put(beanName, beanDefinition);
* 把beanName作为key,beanDefinition作为value,放到map里面
* b.beanDefinitionNames就是一个List<String>,这里就是把beanName放到List中去
* DefaultListableBeanFactory就是我们所说的容器,里面放着beanDefinitionMap, beanDefinitionNames,
* beanDefinitionMap是一个hashMap,beanName作为Key,beanDefinition作为Value,
* beanDefinitionNames是一个集合,里面存放了beanName
*/
private static BeanDefinitionHolder registerPostProcessor(
BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
// 核心已在上方注释
registry.registerBeanDefinition(beanName, definition);
return new BeanDefinitionHolder(definition, beanName);
}
逻辑就是:
- 判断容器中是否已经存在了
ConfigurationClassPostProcessor
Bean - 如果不存在,就通过 RootBeanDefinition 的构造方法获得
ConfigurationClassPostProcessor
的BeanDefinition - 执行
registerPostProcessor()
方法,其内部就是注册Bean(与其他 Bean 注册流程一致)
internalConfigurationAnnotationProcessor
ConfigurationClassPostProcessor 是 Spring 中极其重要的一个类,它实现 BeanDefinitionRegistryPostProcessor 接口,BeanDefinitionRegistryPostProcessor 接口又扩展了 BeanFactoryPostProcessor 接口,BeanFactoryPostProcessor 是 Spring 的扩展点之一。
至此加载完以下扩展点(beanDefinition -> beanDefinitionMap)
第四步:创建 BeanDefinition 扫描器 (ClassPathBeanDefinitionScanner)
初始化 classPath 类型的 BeanDefinition 扫描器,使用场景极少,仅外部手动调用扫描使用,常规方式是不会用到 scanner 对象的此处扫描器仅用于自定义的扫描applicationContext.scan()
。
至此this()方法结束
register(annotatedClasses);分析开始
第五步:注册配置类为BeanDefinition (register(annotatedClasses);)
/**
* 注册配置类
* 把传入的类进行注册,分为两种情况
* a. @Configuration的配置类
* b. 传入普通 Bean (基本不会这么做)
* Spring把配置类分为两种
* a. 带@Configuration注解的配置类称之为FULL配置类
* b. 不带@Configuration注解,是带有@Component,@Import,@ImportResouce,
* @Service, @ComponentScan等注解的配置类称之为Lite配置类
*/
register(componentClasses);
public void register(Class<?>... componentClasses) {
this.reader.register(componentClasses);
}
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {
// AnnotatedGenericBeanDefinition可以理解为一种数据结构,是用来描述Bean的,这里的作用就是把传入
// 的标记了注解的类转为AnnotatedGenericBeanDefinition数据结构,里面有一个getMetadata方法,可以拿到类上的注解
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
// 判断是否需要跳过注解,spring中有一个@Condition注解,当不满足条件,这个bean就不会被解析
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(supplier);
// 解析bean的作用域,如果没有设置的话,默认为单例
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
// 获得beanName
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
// 解析通用注解,填充到AnnotatedGenericBeanDefinition,
// 解析的注解 Lazy,Primary,DependsOn,Role,Description
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));