文章目录
- 【README】
- 【1】基于java配置的spring容器
- 【2】spring容器初始化代码
- 【2.1】实例化容器AnnotationConfigApplicationContext
- 【2.2】注册配置类BeanDefinition
- 【2.3】刷新容器(主要是实例化bean)【重要】
- 【2.3.1】刷新容器步骤概述
【README】
1)本文使用了spring-6.1.10制品库;
2)本文使用AnnotationConfigApplicationContext容器类型(注解配置应用容器), 基于java配置构建spring应用,无需xml配置;
3)基于spring构建应用系统分为2个阶段(或者狭义理解为spring容器启动过程分为2个阶段):
- 容器初始化阶段:
- 实例化容器,BeanDefinition读取器,类路径扫描器;
- 准备环境,包括注册属性bean(如os环境变量,jvm系统变量)到容器;
- 注册BeanFactory后置处理器并触发其后置处理方法,包括触发BeanDefinition注册后置处理器(使用扫描器与读取器读取并注册BeanDefinition到容器),触发BeanFactory后置处理器(如增强配置类);
- 注册Bean后置处理器到容器(用户自定义的Bean后置处理器);
- 注册消息源MessageSource到容器,用于国际化;
- 注册应用事件多播器到容器,用于发布spring各阶段事件;
- 注册应用监听器到容器,用于监听spring事件;
- bean实例化阶段:大致思想是根据BeanDefinition实例化bean;
4)补充:
- 实例化:就是创建或new的意思;
- 初始化:可以简单理解为设置属性,装配依赖bean;
【1】基于java配置的spring容器
【JavaBasedContainerUsingSeveralJavaConfigMain】
public class JavaBasedContainerUsingSeveralJavaConfigMain {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); // 实例化容器
System.out.println("before register()");
context.register(AppConfig00.class, AppConfig02.class); // 注册配置类BeanDefinition
System.out.println("after register()");
context.refresh(); // 刷新容器(最主要的步骤是实例化bean)
System.out.println("after refresh()");
context.getBean(HelloService.class).sayHello("Musk");
context.getBean(HelloService02.class).sayHello("Trump");
}
}
【运行日志】
before register()
after register()
AppConfig00 构造器
AppConfig02 构造器
after refresh()
HelloService#sayHell(): hello Musk
HelloService2#sayHell(): hello Trump
【配置类】
@Configuration
public class AppConfig00 {
public AppConfig00() {
System.out.println("AppConfig00 构造器");
}
@Bean
public HelloService helloService() {
return new HelloService();
}
}
【服务类】
public class HelloService {
public void sayHello(String user) {
System.out.println("HelloService#sayHell(): hello " + user);
}
}
【pom.xml】 参见 pom.xml
【2】spring容器初始化代码
【2.1】实例化容器AnnotationConfigApplicationContext
1)实例化容器:AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); // 实例化容器
【AnnotationConfigApplicationContext 】 实例化容器, BeanDefinition读取器,类路径BeanDefinition扫描器
public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {
// ...
}
public AnnotationConfigApplicationContext() {
StartupStep createAnnotatedBeanDefReader = getApplicationStartup().start("spring.context.annotated-bean-reader.create");
// 实例化 BeanDefinition读取器
this.reader = new AnnotatedBeanDefinitionReader(this);
createAnnotatedBeanDefReader.end();
// 实例化 类路径BeanDefinition扫描器
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
【GenericApplicationContext】 实例化BeanFactory,类型为DefaultListableBeanFactory;
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
【2.2】注册配置类BeanDefinition
1)调用context.register(AppConfig00.class, AppConfig02.class); 注册配置类BeanDefinition ;
AnnotationConfigApplicationContext#register()方法接着调用this.reader.register(componentClasses);
【AnnotationConfigApplicationContext】
public void register(Class<?>... componentClasses) {
Assert.notEmpty(componentClasses, "At least one component class must be specified");
StartupStep registerComponentClass = getApplicationStartup().start("spring.context.component-classes.register")
.tag("classes", () -> Arrays.toString(componentClasses));
this.reader.register(componentClasses); // 使用BeanDefinition阅读器注册给定class的BeanDefinition
registerComponentClass.end();
}
【doRegisterBean】注册给定class的BeanDefinition
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {
// 实例化 BeanDefinition
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setAttribute(ConfigurationClassUtils.CANDIDATE_ATTRIBUTE, Boolean.TRUE);
abd.setInstanceSupplier(supplier);
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
// 处理公共BeanDefinition注解(包括@Lazy, @Primary, @DependsOn, )
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
if (customizers != null) {
for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(abd);
}
}
// 实例化BeanDefinitionHolder, BeanDefinition持有器
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
// 注册BeanDefinition
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
// 注册BeanDefinition, registry实际就是AnnotationConfigApplicationContext(spring容器本身)
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
String beanName = definitionHolder.getBeanName();
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
String[] var4 = aliases;
int var5 = aliases.length;
for(int var6 = 0; var6 < var5; ++var6) {
String alias = var4[var6];
registry.registerAlias(beanName, alias);
}
}
}
【2.3】刷新容器(主要是实例化bean)【重要】
1)调用context.refresh(); 刷新容器;
【AbstractApplicationContext#refresh()】刷新容器
public void refresh() throws BeansException, IllegalStateException {
this.startupShutdownLock.lock();
try {
this.startupShutdownThread = Thread.currentThread();
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// 1 刷新容器的准备工作,包括初始化属性源,并校验属性,保存应用监听器;
// Prepare this context for refreshing.
prepareRefresh();
// 2 默认实现:获取最新容器,包括把容器hashcode赋值给BeanFactory的序列化id
// 也可以由子类来刷新内部BeanFactory
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 3 初始化BeanFactory
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// 4 protected方法,允许子类自行定义BeanFactory的后置处理逻辑
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// 5 触发BeanFacotry后置处理器
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// 6 注册Bean后置处理器
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// 7 初始化消息源 ,用于国际化
// Initialize message source for this context.
initMessageSource();
// 8 初始化应用事件多播器
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// 9 子类可以重写的模板方法,以添加特定于上下文的刷新工作。在实例化单例之前,在初始化特殊 bean 时调用;
// Initialize other special beans in specific context subclasses.
onRefresh();
// 10 注册监听器,包括应用事件多播器
// Check for listener beans and register them.
registerListeners();
// 11 实例化所有剩余的单例bean
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// 12 容器刷新的收尾工作,包括清空缓存,注册生命周期处理器并执行其onRefresh(),发布ContextRefreshedEvent事件;
// Last step: publish corresponding event.
finishRefresh();
}
catch (RuntimeException | Error ex ) {
// 异常1: 销毁bean
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
contextRefresh.end();
}
}
finally {
this.startupShutdownThread = null;
this.startupShutdownLock.unlock();
}
}
【2.3.1】刷新容器步骤概述
1)刷新容器步骤:
step1)prepareRefresh():刷新容器的准备工作,包括初始化属性源,并校验属性,保存应用监听器;
step2)obtainFreshBeanFactory():获取最新容器,包括把容器hashcode赋值给BeanFactory的序列化id
step3)prepareBeanFactory(beanFactory):初始化BeanFactory,包括设置属性(类加载器,属性编辑器注册器),注册单例(environment,systemProperties系统属性,systemEnvironment环境变量),新增BeanPostProcessor(ApplicationContextAwareProcessor,ApplicationListenerDetector)
step4)postProcessBeanFactory(beanFactory):protected方法,允许子类自行定义BeanFactory的后置处理逻辑;
step5)invokeBeanFactoryPostProcessors(beanFactory):触发BeanFacotry后置处理器,包括触发BeanDefinition注册后置处理器(注册配置类及其方法的BeanDefinition),触发BeanFactory后置处理器(增强配置类,新增Bean后置处理器ImportAwareBeanPostProcessor,新增事件监听器方法处理器EventListenerMethodProcessor)
step6)registerBeanPostProcessors(beanFactory): 注册Bean后置处理器;
step7)initMessageSource(): 初始化消息源,包括注册name=messageSource且类型=DelegatingMessageSource的bean;
step8)initApplicationEventMulticaster(): 初始化应用事件多播器,包括注册name=applicationEventMulticaste且类型=SimpleApplicationEventMulticaster的bean;
step9)onRefresh():可以重写的模板方法,以添加特定于上下文的刷新工作。在实例化单例之前,在初始化特殊 bean 时调用;
step10)registerListeners():注册监听器,包括应用事件多播器(ApplicationEventMulticaster)添加应用监听器(ApplicationListener)及多播应用事件;
step11)finishBeanFactoryInitialization(): 实例化所有剩余的单例bean, 包括新增嵌入值解析器(如PropertySourcesPlaceholderConfigurer),冻结配置信息,实例化单例bean ;
step12)finishRefresh(): 容器刷新的收尾工作,包括清空缓存,注册生命周期处理器DefaultLifecycleProcessor(name=lifecycleProcessor)并执行其onRefresh(),发布ContextRefreshedEvent事件;
2)刷新容器步骤小结:
- 初始化BeanFactory,包括设置属性,注册属性单例,注册Bean后置处理器;
- 触发BeanFactory后置处理器, 包括触发BeanDefinition注册后置处理器以注册BeanDefinition,BeanFactory后置处理器;
- 注册Bean后置处理器;
- 初始化MessageSource,用于国际化;
- 实例化应用事件多播器,应用监听器,用于发布spring启动事件通知订阅者;
- 根据BeanDefinition实例化bean(最重要)-finishBeanFactoryInitialization() ;