共计 16832 个字符,预计需要花费 43 分钟才能阅读完成。
首先看一段代码,我们通过这段代码分析 ioc 的加载过程。
public static void main(String[] args) {ApplicationContext applicationContext = new AnnotationConfigApplicationContext( MainConfig.class);
Person bean = applicationContext.getBean(Person.class);
System.out.println(bean);
String[] namesForType = applicationContext.getBeanNamesForType( Person.class);
for (String name : namesForType) {System.out.println(name);
}
}
通过上面的代码,可以看到是通过 ApplicationContext 加载 ioc 容器的。下面我们来看一下 AnnotationConfigApplicationContext 执行的具体流程,主要分为下面几步:
- 初始化一个空容器,容器中不包含任何 Bean 信息。
- 为容器中注册一个要被处理的注解 Bean
- 刷新容器
// 创建 ioc 容器
// 最常用的构造函数,通过将涉及到的配置类传递给该构造函数,以实现将相应配置类中的 Bean 自动注册到容器中
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {//1. 初始化一个空容器,容器不包含任何 Bean 信息,需要在稍后通过调用其 register() 方法注册配置类,并调用 refresh() 方法刷新容器,触发容器对注解 Bean 的载入、解析和注册过程
this();
//2. 为容器中注册一个要被处理的注解 Bean,新注册的 Bean,必须手动调用容器的 refresh() 方法刷新容器,触发容器对新注册的 Bean 的处理
register(annotatedClasses);
//3. 刷新容器
refresh();}
附一张时序图,大家可以结合代码理解(图片来源网络)
1. 初始化一个空容器
// 默认构造函数,初始化一个空容器,容器不包含任何 Bean 信息,需要在稍后通过调用其 register() 方法注册配置类,并调用 refresh() 方法刷新容器,触发容器对注解 Bean 的载入、解析和注册过程
public AnnotationConfigApplicationContext() {this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
2. 为容器注册一个要被处理的注解 Bean
// 为容器中注册一个要被处理的注解 Bean,新注册的 Bean,必须手动调用容器的 refresh() 方法刷新容器,触发容器对新注册的 Bean 的处理
public void register(Class<?>... annotatedClasses) {Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
this.reader.register(annotatedClasses);
}
2.1 注册自定义注解 Bean
// 注册多个注解 Bean 自定义类
public void register(Class<?>... annotatedClasses) {for (Class<?> annotatedClass : annotatedClasses) {registerBean(annotatedClass);
}
}
/**
* Register a bean from the given bean class, deriving its metadata from
* class-declared annotations.
* @param annotatedClass the class of the bean
*/
// 注册一个注解 Bean 定义类
public void registerBean(Class<?> annotatedClass) {doRegisterBean(annotatedClass, null, null, null);
}
//Bean 定义读取器向容器注册注解 Bean 定义类
<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
// 根据指定的注解 Bean 定义类,创建 Spring 容器中对注解 Bean 的封装的数据结构
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {return;}
abd.setInstanceSupplier(instanceSupplier);
// 解析注解 Bean 定义的作用域,若 @Scope("prototype"),则 Bean 为原型类型;若 @Scope("singleton"),则 Bean 为单例类型
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
// 为注解 Bean 定义设置作用域
abd.setScope(scopeMetadata.getScopeName());
// 为注解 Bean 定义生成 Bean 名称
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
// 处理注解 Bean 定义中的通用注解
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
// 如果在向容器注册注解 Bean 定义时,使用了额外的限定符注解,则解析限定符注解。主要是配置的关于 autowiring 自动依赖注入装配的限定条件,即 @Qualifier 注解
//Spring 自动依赖注入装配默认是按类型装配,如果使用 @Qualifier 则按名称
if (qualifiers != null) {for (Class<? extends Annotation> qualifier : qualifiers) {
// 如果配置了 @Primary 注解,设置该 Bean 为 autowiring 自动依赖注入装配时的首选
if (Primary.class == qualifier) {abd.setPrimary(true);
}
// 如果配置了 @Lazy 注解,则设置该 Bean 为非延迟初始化,如果没有配置,则该 Bean 为预实例化
else if (Lazy.class == qualifier) {abd.setLazyInit(true);
}
// 如果使用了除了 @Primary 和 @Lazy 以外的其他注解,则为该 Bean 添加一个 autowiring 自动依赖注入装配限定符,该 Bean 在进 autowiring 自动依赖注入装配时,根据名称装配限定符指定的 Bean
else {abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
for (BeanDefinitionCustomizer customizer : definitionCustomizers) {customizer.customize(abd);
}
// 创建一个指定 Bean 名称的 Bean 定义对象,封装直接 Bean 定义类数据
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
// 根据注解 Bean 定义类中配置的作用域,创建响应的代理对象
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
// 向 IOC 容器注册注解 Bean 类定义对象
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
3. 刷新容器
@Override
public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
// 刷新前的预处理
//1、调用容器准备刷新的方法,获取容器的当前时间,同时给容器设置同步标识
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// 初始化 BeanFactory
//2. 告诉子类启动 refreshBeanFactory() 方法,Bean 定义资源文件的载入从子类的 refreshBeanFactory() 方法启动
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
//BeanFactory 的预准备工作
//3、为 BeanFactory 配置容器特性,例如类加载器、事件处理器等
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
//BeanFactory 的后置处理器
//4、为容器的某些子类指定特殊的 BeanPost 事件处理器
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
//5、调用所有注册的 BeanFactoryPostProcessor 的 Bean
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
//Bean 的后置处理器
//6、为 BeanFactory 注册 BeanPost 事件处理器
//BeanPostProcessor 是 Bean 后置处理器,用于监听容器触发的事件
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
//7、初始化信息源,和国际化相关
initMessageSource();
// Initialize event multicaster for this context.
//8、初始化容器事件传播器
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
//9、调用子类的某些特殊 Bean 初始化方法
onRefresh();
// Check for listener beans and register them.
//10、为事件传播器注册事件监听器
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
//11、初始化所有剩余的单例 Bean
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
//12、初始化容器的生命周期事件处理器,并发布容器的声明周期事件
finishRefresh();}
catch (BeansException ex) {if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization -" +
"cancelling refresh attempt:" + ex);
}
// Destroy already created singletons to avoid dangling resources.
//13、销毁已创建的 Bean
destroyBeans();
// Reset 'active' flag.
//14、取消 refresh 操作,重置容器的同步标识
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
//15、重设公共缓存
resetCommonCaches();}
}
}
3.1 调用容器准备刷新的方法,获取容器的当前时间,同时给容器设置同步标识(刷新前的预处理)
protected void prepareRefresh() {
// Switch to active.
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
if (logger.isDebugEnabled()) {if (logger.isTraceEnabled()) {logger.trace("Refreshing" + this);
}
else {logger.debug("Refreshing" + getDisplayName());
}
}
// Initialize any placeholder property sources in the context environment.
// 初始化一些属性设置,子类自定义个性化的属性设置方法
initPropertySources();
// Validate that all properties marked as required are resolvable:
// see ConfigurablePropertyResolver#setRequiredProperties
// 检查属性的合法性等
getEnvironment().validateRequiredProperties();
// Store pre-refresh ApplicationListeners...
if (this.earlyApplicationListeners == null) {
// 保存容器中的一些早期的事件
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
// Reset local application listeners to pre-refresh state.
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
// Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
this.earlyApplicationEvents = new LinkedHashSet<>();}
3.2 告诉子类启动 refreshBeanFactory() 方法,Bean 定义资源文件的载入从子类的 refreshBeanFactory() 方法启动
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
// 刷新【创建】BeanFactory
// 这里使用了委派设计模式,父类定义了抽象的 refreshBeanFactory() 方法,具体实现调用子类容器的 refreshBeanFactory() 方法
refreshBeanFactory();
// 返回刚才 GenericApplicationContext 创建的 BeanFactory 对象
// 将创建的 BeanFactory【DefaultListableBeanFactory】返回
return getBeanFactory();}
3.2.1 刷新(创建)BeanFactory
@Override
protected final void refreshBeanFactory() throws IllegalStateException {if (!this.refreshed.compareAndSet(false, true)) {
throw new IllegalStateException("GenericApplicationContext does not support multiple refresh attempts: just call'refresh'once");
}
this.beanFactory.setSerializationId(getId());
}
3.2.2 返回刚才 GenericApplicationContext 创建的 BeanFactory 对象
@Override
public final ConfigurableListableBeanFactory getBeanFactory() {return this.beanFactory;}
3.3 为 BeanFactory 配置容器特性,例如类加载器、事件处理器等(BeanFactory 的预准备工作)
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
//1、设置 BeanFactory 的类加载器、支持表达式解析器
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
//2、添加部分 BeanPostProcessor【ApplicationContextAwareProcessor】beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//3、设置忽略的自动装配的接口 EnvironmentAware、EmbeddedValueResolverAware、xxx
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
//4、注册可以解析的自动装配:我们能直接在任何组件中自动注入:BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// Register early post-processor for detecting inner beans as ApplicationListeners.
//5、添加 BeanPostProcessor【ApplicationListenerDetector】beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// Register default environment beans.
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
3.4 为容器的某些子类指定特殊的 BeanPost 事件处理器
@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {if (this.servletContext != null) {beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
}
WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext);
}
3.5 调用所有注册的 BeanFactoryPostProcessor 的 Bean
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
3.6 为 BeanFactory 注册 BeanPost 事件处理器(Bean 的后置处理器)
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
3.7 初始化信息,和国际化相关
protected void initMessageSource() {ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
// Make MessageSource aware of parent MessageSource.
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
// Only set parent context as parent MessageSource if no parent MessageSource
// registered already.
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
if (logger.isTraceEnabled()) {logger.trace("Using MessageSource [" + this.messageSource + "]");
}
}
else {
// Use empty MessageSource to be able to accept getMessage calls.
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
this.messageSource = dms;
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
if (logger.isTraceEnabled()) {logger.trace("No'" + MESSAGE_SOURCE_BEAN_NAME + "'bean, using [" + this.messageSource + "]");
}
}
}
3.8 初始化容器事件传播器
protected void initApplicationEventMulticaster() {ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isTraceEnabled()) {logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isTraceEnabled()) {
logger.trace("No'" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "'bean, using" +
"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
}
}
}
3.9 调用子类的某些特殊 Bean 初始化方法
@Override
protected void onRefresh() {this.themeSource = UiApplicationContextUtils.initThemeSource(this);
}
3.10 为事件传播器注册事件监听器
protected void registerListeners() {
// Register statically specified listeners first.
for (ApplicationListener<?> listener : getApplicationListeners()) {getApplicationEventMulticaster().addApplicationListener(listener);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// Publish early application events now that we finally have a multicaster...
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {for (ApplicationEvent earlyEvent : earlyEventsToProcess) {getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
3.11 初始化所有剩余的单例 Bean
// 对配置了 lazy-init 属性的 Bean 进行预实例化处理
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
// 这是 Spring3 以后新加的代码,为容器指定一个转换服务 (ConversionService)
// 在对某些 Bean 属性进行转换时使用
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
if (!beanFactory.hasEmbeddedValueResolver()) {beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
// 为了类型匹配,停止使用临时的类加载器
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
// 缓存容器中所有注册的 BeanDefinition 元数据,以防被修改
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
// 对配置了 lazy-init 属性的单态模式 Bean 进行预实例化处理
beanFactory.preInstantiateSingletons();}
3.12 初始化容器的生命周期事件处理器,并发布容器的声明周期事件
protected void finishRefresh() {// Clear context-level resource caches (such as ASM metadata from scanning).
clearResourceCaches();
// Initialize lifecycle processor for this context.
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
getLifecycleProcessor().onRefresh();
// Publish the final event.
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}
3.13 销毁已创建的 Bean
protected void destroyBeans() {getBeanFactory().destroySingletons();}
3.14 取消 refresh 操作,充值容器的同步标识
@Override
protected void cancelRefresh(BeansException ex) {this.beanFactory.setSerializationId(null);
super.cancelRefresh(ex);
}
3.15 重设公共缓存
protected void resetCommonCaches() {ReflectionUtils.clearCache();
AnnotationUtils.clearCache();
ResolvableType.clearCache();
CachedIntrospectionResults.clearClassLoader(getClassLoader());
}
正文完