spring源码分析 - AnnotationConfigApplicationContext启动之reader、scanner、register逻辑整理

前言

我们在使用spring framework时一般都喜欢按照以下方式写启动

AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);

而我们的AnnotationConfigApplicationContext的内容如下

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {

// 构造DefaultListableBeanFactory、AnnotatedBeanDefinitionReader、ClassPathBeanDefinitionScanner

this();

register(componentClasses);

refresh();

}

其中的this()部分如下:

public AnnotationConfigApplicationContext() {

StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");

// 额外会创建StandardEnvironment

this.reader = new AnnotatedBeanDefinitionReader(this);

createAnnotatedBeanDefReader.end();

this.scanner = new ClassPathBeanDefinitionScanner(this);

}

其实主要是生成类的reader、scanner、生成AppConfig.class的beandefinition

以下是AnnotationConfigApplicationContext类的继承结构图

下面我们来整理一下AnnotationConfigApplicationContext启动除了除子refresh()以外内容

1.factory生成

beanfactory使用的是GenericApplicationContext的beanfactory,类是DefaultListableBeanFactory,其中instantiationStrategy用类文件读取方式是由系统环境参数org.graalvm.nativeimage.imagecode是否存在决定,如存在用SimpleInstantiationStrategy,不存在用CglibSubclassingInstantiationStrategy,他们两关系如下:

public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationStrategy

他们的差别就是一个java反射的原理生成instance,另外一个可以利cglib方式生成instance

另外还有DefaultResourceLoader中的classloader生成,主要是利用当前线程的 Thread.currentThread().getContextClassLoader()来生成

2.生成reader AnnotatedBeanDefinitionReader

1) 创建生成StandardEnvironment

2) 生成conditionEvaluator,主要是为了@Conditional,通过生成ConditionEvaluator对象,其中context属性主要是通过生成ConditionContextImpl对象,主对指定了beanfactory、environment、resourceloader、classloader,这里的resourceloader其实还是指定AnnotationConfigApplicationContext对象,因为他是实现了接口BeanDefinitionRegistry

this.resourceLoader = (resourceLoader != null ? resourceLoader : deduceResourceLoader(registry));

而这里的resourceLoader传进来的参数为空,所以需使用deduceResourceLoader方法,而这里的registry是AnnotationConfigApplicationContext对象

private ResourceLoader deduceResourceLoader(@Nullable BeanDefinitionRegistry source)

3) registerAnnotationConfigProcessors,主要为解析class生成object

    a. 首先设定beanfactory比较器

       beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE)

b. 然在在设定beanfactory的autowireCandidateResolver,主要用检查是否以autowired有关的内容

    beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver())

c. 向beanfactory中的 beanDefinitionMap中注册了如下类的BeanDefinition

ConfigurationClassPostProcessor、AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、PersistenceAnnotationBeanPostProcessor、EventListenerMethodProcessor、DefaultEventListenerFactory

2.生成scanner ClassPathBeanDefinitionScanner

1)向includeFilters里注册扫描注解

Component.class、javax.annotation.ManagedBean、javax.inject.Named

2)设定environment StandardEnvironment

3) 设定ResourceLoader

3.利用reader注册config类

1)生成启动configuration类的AnnotatedGenericBeanDefinition

a. 设定beanClass属性,主要利用传进来的class来设定

b. 设定metadata,主要是利用AnnotationMetadata.introspect(beanClass)返回StandardAnnotationMetadata对象

  • 设定introspectedClass属性
  • 设定mergedAnnotations属性,通过MergedAnnotations.from(introspectedClass,SearchStrategy.INHERITED_ANNOTATIONS, RepeatableContainers.none())
    • 通过isKnownEmpty检查类以下内容:
  1. 是否 满足条件(type.getName().startsWith("java.") || type == Ordered.class)
  2. .是否继承其他类
  3. .检查source.getDeclaredAnnotations内的method返回type满足(type == Class.class || type == Class[].class || type.isEnum())条件是否会抛异常
  • 返回生成TypeMappedAnnotations对象

2)判断以下条件是否需要跳过注册

      1. 1.检查1中的metadata是否正常生成
      2. 2.检查类不是Conditional.class
      3. 3.检查是否为接口
      4. 4.检查是否为component、conponentscan、import、importresource其中之一
      5. 5.检查是否有方法

满足1和2不检查3、4、5的条件

3)得到类的scope信息,scope信息中如有proxyMode并且设定,若没有scope相关信息设定默认值为singleton,proxymode为NO

4)生成beanname,如果class名前两位大写不变,否则会将第一位变成小写

5)在AnnotatedBeanDefinition中设定类中以下注解类的值

@Lazy、@Primary、@DependsOn、@Role、@Description

6)在beanfactory中生成最终中beandifinition,且如果scope信息中有proxy信息,会重新生成proxy的bendefinition按照bean名字替换原有的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值