概述
在Spring框架中,启动时需要扫描并加载应用程序中的Bean。本文将探究Spring 5.3.0版本中基于注解的Bean扫描过程,帮助读者深入了解Spring框架的工作原理.
容器启动
首先让我们使用基于注解的方式启动Spring容器,传入一个配置类,如下代码:
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
让我们进入该构造方法看下,很简洁只有三行代码
// 创建一个新的AnnotationConfigApplicationContext对象
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
// 调用无参构造函数
this();
// 注册配置类
register(componentClasses);
// 刷新容器,完成容器的初始化和启动过程
refresh();
}
this()
在Java中,子类继承了父类的属性和方法,而构造函数也是类的一部分。
由于 AnnotationConfigApplicationContext 继承 GenericApplicationContext,所以会先调用GenericApplicationContext的无参构造.
// AnnotationConfigApplicationContext的无参构造
public AnnotationConfigApplicationContext() {
StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
this.reader = new AnnotatedBeanDefinitionReader(this);
createAnnotatedBeanDefReader.end();
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
// GenericApplicationContext的无参构造
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
// 综上this()方法
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
this.beanFactory = new DefaultListableBeanFactory();
- AnnotatedBeanDefinitionReader
Spring框架中的一个类,用于读取并解析带有注解的Bean定义。它可以通过扫描类路径、指定包名或通过指定类来读取带有注解的Bean定义.- ClassPathBeanDefinitionScanner
Spring框架中的一个类,用于在类路径上扫描并解析Bean定义。它可以根据指定的包名或类来扫描对应的类,并将其转换为Bean定义。它使用了BeanDefinitionRegistry来注册和管理扫描到的Bean定义.- DefaultListableBeanFactory
Spring框架中的一个类,实现了BeanDefinitionRegistry和ConfigurableListableBeanFactory接口。它是Spring的默认的可列表的Bean工厂实现类,负责注册、管理和获取Bean实例.
注
1.this.reader = new AnnotatedBeanDefinitionReader(this);
该实例化AnnotatedBeanDefinitionReader时会构造用于注册注解驱动的Bean后置处理器和相关的解析器。
2.this.scanner = new ClassPathBeanDefinitionScanner(this);
该实例化会添加默认的注解类型过滤this.includeFilters.add(new AnnotationTypeFilter(Component.class));后续文件扫描会使用
// 进入方法
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
// 继续进入
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
registerAnnotationConfigProcessors(registry, null);
}
// 提前注册必要的后置处理器
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
// 检查并设置DefaultListableBeanFactory的依赖比较器和自动装配候选解析器
// 以确保它们是AnnotationAwareOrderComparator和ContextAnnotationAutowireCandidateResolver的实例
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
// 用于保存注册的BeanDefinitionHolder的集合
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
// 注册ConfigurationClassPostProcessor(用于处理@Configuration注解和相关注解的后置处理器)
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));
}
// 注册AutowiredAnnotationBeanPostProcessor(用于处理@Autowired和相关注解的后置处理器)
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));
}
// 检查并添加CommonAnnotationBeanPostProcessor(处理JSR-250注解的后置处理器)
// 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));
}
// 检查并添加PersistenceAnnotationBeanPostProcessor(处理JPA注解的后置处理器)
// 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));
}
// 注册EventListenerMethodProcessor(用于处理@EventListener注解的后置处理器)
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));
}
// 注册DefaultEventListenerFactory(用于创建事件监听器的工厂Bean)
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;
}
register(componentClasses)
向AnnotationConfigApplicationContext或其子类注册配置类的方法。它接受一个或多个配置类作为参数,将这些配置类转换为BeanDefinition并注册到容器中。
进入方法
public void register(Class<?>... componentClasses) {
Assert.notEmpty(componentClasses, "At least one component class must be specified");
StartupStep registerComponentClass = this.getApplicationStartup().start("spring.context.component-classes.register")
.tag("classes", () -> Arrays.toString(componentClasses));
// 只需要关注该行代码
this.reader.register(componentClasses);
registerComponentClass.end();
}
进入this.reader.register(componentClasses);
// 遍历传入的componentClasses参数,其中每个元素代表一个配置类
public void register(Class<?>... componentClasses) {
for (Class<?> componentClass : componentClasses) {
registerBean(componentClass);
}
}
// 我们这里只有一个class -> MainConfig.class
让我们进入registerBean(componentClass);
doRegisterBean(beanClass, null, null, null, null);
// 继续进入
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {
// 1.创建一个AnnotatedGenericBeanDefinition对象,用于保存Bean定义的元数据
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
// 2.检查是否应该跳过当前Bean定义,根据条件表达式的结果判断
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(supplier);
// 3.解析Bean的作用域信息,并设置到Bean定义中
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
// 4.生成Bean的名称,如果没有指定名称则由BeanNameGenerator生成
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
// 5.处理常见的定义注解,如@Primary、@Lazy等(将信息封装进BeanDefinition)
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
// 6.处理限定符注解,如@Qualifier、@Primary、@Lazy等
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));
}
}
}
if (customizers != null) {
for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(abd);
}
}
// 7.创建一个Bean定义持有者,用于保存Bean定义和名称
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
// 8.根据作用域信息应用代理模式,如果需要创建代理则应用ScopedProxyMode
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
// 9.注册Bean定义到BeanDefinitionRegistry中
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
总结上述流程,reader就是将配置类转化为BeanDefinition,然后我们进入下一步
// 注册BeanDefinition到BeanDefinitionRegistry中
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
// 进入方法
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// 注册主要名称的Bean定义
String beanName = definitionHolder.getBeanName();
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// 注册别名
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
现在让我们进入方法
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// 这里我们只看关键的代码,其他省略
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
...
// 获取已存在的BeanDefinition
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
...
// 将当前BeanDefinition替换已存在的BeanDefinition
this.beanDefinitionMap.put(beanName, beanDefinition);
}else{
// 如果不存在同名的BeanDefinition,将当前BeanDefinition注册到beanDefinitionMap中
if (hasBeanCreationStarted()) {
// Cannot modify startup-time collection elements anymore (for stable iteration)
// 如果已经开始创建Bean,则使用同步块来添加BeanDefinition,以确保线程安全
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;
removeManualSingletonName(beanName);
}
}
else {
// 当前我们会进入这个条件中-> 将bean定义放入beanDefinitionMap中
// 如果还在启动阶段,直接添加BeanDefinition到beanDefinitionMap中
// Still in startup registration phase
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
removeManualSingletonName(beanName);
}
this.frozenBeanDefinitionNames = null;
}
}
}
如下图配置类MainConfig已经被注册到BedifinationMap中
refresh()
刷新容器,完成容器的初始化和启动过程.具体看下该方法都做了什么
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 1.刷新预处理,初始化环境变量,验证环境变量必须要有的属性
prepareRefresh();
// 2.主要获取一个Bean工厂,这里是DefaultListableBeanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 3.为使用该上下文准备Bean工厂
prepareBeanFactory(beanFactory);
try {
// 4.在上下文子类中允许对Bean工厂进行后处理
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// 5.调用Bean的后置处理器
invokeBeanFactoryPostProcessors(beanFactory);
// 6.注册我们自己定义的bean后置处理器
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// 7.初始化国际化资源处理器
initMessageSource();
// 8.初始化一个事件广播器,即事件监听器管理
initApplicationEventMulticaster();
// 9.空方法
onRefresh();
// 10.注册监听器,系统的以及程序员自定义的(实现接口ApplicationListener或方法@EventListener)
registerListeners();
// 11.实例化非懒加载到单例Bean
finishBeanFactoryInitialization(beanFactory);
// 12.最后一步:发布相应的事件
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// 销毁已创建的单例Bean以避免悬挂资源
destroyBeans();
// 重置'active'标志
cancelRefresh(ex);
// 将异常传播给调用者
throw ex;
}
finally {
// 重置Spring核心中的常见内省缓存,因为我们可能不再需要单例Bean的元数据...
resetCommonCaches();
contextRefresh.end();
}
}
}
总结
这里只是简单描述了Spring启动的流程,后续会对refresh()方法中的各个部分针对性的学习,例如文件扫描、依赖注入、循环依赖问题、事务、AOP等实现.