前言
我们在使用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检查类以下内容:
- 是否 满足条件(type.getName().startsWith("java.") || type == Ordered.class)
- .是否继承其他类
- .检查source.getDeclaredAnnotations内的method返回type满足(type == Class.class || type == Class[].class || type.isEnum())条件是否会抛异常
- 返回生成TypeMappedAnnotations对象
2)判断以下条件是否需要跳过注册
-
-
- 1.检查1中的metadata是否正常生成
- 2.检查类不是Conditional.class
- 3.检查是否为接口
- 4.检查是否为component、conponentscan、import、importresource其中之一
- 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名字替换原有的