超详细Spring源码解析一:容器初始化
学习java也有几个月了,之前学习完Spring的源码一直没有时间总结(主要是懒),今天抽空回头做了一下复习,就想着将Spring源码的解析和理解分享出来,可能会有不贴切的地方还希望看客海涵指出。
前言
首先让我们看看当我们实例化一个容器时,spring做了什么
//这是我们常用的实例化方式
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(DemoConfig.class);
context.getBean(DemoConfig.class);
构造方法中其实调用了register方法与refresh方法
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
register(annotatedClasses);
refresh();
}
这两个方法非常重要,故为了方便,这里实例化一个空容器并手动注册刷新
//实例化容器
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
//注册配置文件
context.register(DemoConfig.class);
//刷新容器
context.refresh();
//获取bean
System.out.println(context.getBean(DemoConfig.class));
Spring容器的初始化
下面让我们步入正题,当我们实例化一个容器时,首先是完成了两个类的实例化
//一个简便的适配器用于注册带注释的bean类。
this.reader = new AnnotatedBeanDefinitionReader(this);
//用于发现类路径下的候选bean的扫描器
//注册相应的bean到传入的registry中
this.scanner = new ClassPathBeanDefinitionScanner(this);
这是spring两个非常重要的类,先来解析AnnotatedBeanDefinitionReader
AnnotatedBeanDefinitionReader: 用于注册带注释的bean类
AnnotatedBeanDefinitionReader在实例化时完成了registry的赋值,并新建了一个ConditionEvaluator
-
registry(BeanDefinitionRegistry):这里传入的就是我们的容器,容器的父类GenericApplicationContext实现了这个接口
-
ConditionEvaluator :这是一个内部工作的类,用于处理@Conditonal注解
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
//注册一些用于解析注解配置的后置处理器(内置的)
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
最后一个方法为容器注册了一些后置处理器
代码中断点可以发现,实例化容器之后在注册任何类之前,容器里就有6个类了
这6个类(后置处理器)就是在这行代码里完成注册的,为Spring服务
registerAnnotationConfigProcessors方法:为容器注册Spring内置的后置处理器
//拿到applicationContext中的beanFactory(管理bean的工厂)
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
//添加一个比较器,用于支持spring 的ordered接口和@Priority注解的拓展
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
//添加自动装配候选解析器,提供qualifier注解和Lazy注解的支持
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
//BeanDefinitionHolder就只是一个封装了BeanDefinition和beanName的类,为了方便传参
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
//特别重要,在bean的实例化流程中的重要角色
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));
}
//自动装配注解的处理器
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
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));
}
//检查是否支持JSR-250,如果支持,则添加CommonAnnotationBeanPostProcessor。
// 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。
// Check for JPA support, and if present add the 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));
}
//添加事件监听处理器,将EventListener方法作为独立的ApplicationListener实例注册
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));
}
//添加事件监听器工厂,添加对EventListener注解的支持
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));
}
return beanDefs;
其中我们着重解析一下将后置处理器注册进容器的方法registerPostProcessor
registerPostProcessor:注册后置处理器
//用于为beanfactory注册后置处理器
private static BeanDefinitionHolder registerPostProcessor(
BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
//这个标识 说明 提供的是一个完全的背景角色并且与最终用户无关的东西,这个标识在注册完全
//在spring内部工作的bean的时候使用,就是表示这是一个spring的内部bean
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
//注册bean,因为这些都是调用的接口,必须debug进去
registry.registerBeanDefinition(beanName, definition);
return new BeanDefinitionHolder(definition, beanName);
}
其中的setRole主要是用于标识这个bean是用户的还是spring的
然后debug进入registry.registerBeanDefinition(beanName, definition);,其实也可以直接在DefaultListableBeanFactory类中搜索registerBeanDefinition,容器中的bean工厂就是DefaultListableBeanFactory
//参数验证
Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
//验证beanDefinition的有效性
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}
//尝试在beanDefinitionMap中获取已有的BeanDefinition
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
//当BeanDefinition存在并不允许重写时报错
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
"': There is already [" + existingDefinition + "] bound.");
}
//就是检查上面设置的Role的优先级
//就是如果用户设置的bean和spring的内部bean重名了,就打印警告日志
else if (existingDefinition.getRole() < beanDefinition.getRole()) {
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
if (logger.isWarnEnabled()) {
logger.warn("Overriding user-defined bean definition for bean '" + beanName +
"' with a framework-generated bean definition: replacing [" +
existingDefinition + "] with [" + beanDefinition + "]");
}
}
//如果传入的beanDefinition与现有的beanDefinition不相同,打印警告日志
else if (!beanDefinition.equals(existingDefinition)) {
if (logger.isInfoEnabled()) {
logger.info("Overriding bean definition for bean '" + beanName +
"' with a different definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
else {
if (logger.isDebugEnabled()) {
logger.debug("Overriding bean definition for bean '" + beanName +
"' with an equivalent definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
//最后将beanDefinition 放入 beanDefinitionMap中
this.beanDefinitionMap.put(beanName, beanDefinition);
}
//如果没有BeanDefinition存在
else {
//检查这个工厂的bean创建阶段是否已经开始,即是否有任何bean被标记为同时创建。
if (hasBeanCreationStarted()) {
// Cannot modify startup-time collection elements anymore (for stable iteration)
synchronized (this.beanDefinitionMap) {
this.beanDefinitionMap.put(beanName, beanDefinition);
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
if (this.manualSingletonNames.contains(beanName)) {
Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
updatedSingletons.remove(beanName);
this.manualSingletonNames = updatedSingletons;
}
}
}
//初始化时在这注册
// Still in startup registration phase
else {
//注册
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
this.manualSingletonNames.remove(beanName);
}
this.frozenBeanDefinitionNames = null;
}
到这里AnnotatedBeanDefinitionReader方法的实例化就结束了,他的实例化主要是完成属性的赋值并为容器添加了6个后置处理器。
现在来解析实例化的另一个类ClassPathBeanDefinitionScanner
ClassPathBeanDefinitionScanner: 用于发现类路径下的候选bean的扫描器
这个类的实例化比较简单,实例化是仅仅只是完成了属性的赋值
//设置环境与资源加载器
setEnvironment(environment);
setResourceLoader(resourceLoader);
到这里Spring容器的初始化结束
小总结
容器初始化时实例化了两个类
AnnotatedBeanDefinitionReader: 用于注册带注释的bean类,并在实例化时为容器注册了六个内置的后置处理器
ClassPathBeanDefinitionScanner: 用于发现类路径下的候选bean的扫描器
到这里源码的内容都十分简单,应该都不难理解,上面提到的register方法,refresh方法,getBean方法共同完成了bean的注册实例化这些解析会在后续的分享中逐渐解析总结
Github源码地址 持续更新中
上述的解析中若有不贴切或错误的地方,还请看客包含并指出,感谢~