前言
现在基本上所有的Java项目都会用spring,那么在项目启动的过程中是如何启动spring的?spring的入口有很多,有的使用xml,有的使用注解,但总归都是ApplicationContext的实现类,通过创建ApplicationContext的对象来启动spring。
从demo看启动过程
通过注解配置的方式,来看看spring是如何启动的
public class Main {
public static void main(String[] args) {
//ZTest1Config.class注解配置类
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ZTest1Config.class);
}
}
可以看到启动spring只需一行代码,创建一个对象,那么创建这个对象时做了哪些事?
/**
* 1.创建一个新的容器,初始化容器的相关资源,为后续使用。初始化两大成员: AnnotatedBeanDefinitionReader ,ClassPathBeanDefinitionScanner
* 2.注册配置类
* 3.刷新容器
* @param componentClasses 注解配置类,可以有多个
*/
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();
register(componentClasses);
refresh();
}
创建AnnotationConfigApplicationContext对象时,做了以上三件事,对应以上三个方法(前两个方法是在准备环境,核心在第三个),在进一步探索这三个方法是如何实现的
调用无参构造
首先它会调用自己的无参构造,初始化必要的成员。
/*
* 这里创建spring容器的两大成员
* 1.注解的bean定义读取器:
* a.创建ConditionEvaluator,主要记录了容器的重要信息
* b.给bean工厂注册各种后置处理器。
* 2.类路劲的bean定义扫描器:
* a.注册了扫描过滤器。哪些注解的bean是需要被扫描的
* b.内部创建了一个元数据缓存工厂,为了后面初始化bean存储类以及类的文件信息
*
* */
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);
}
上面创建了AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner。这两个类都是Spring中用来读取Bean定义信息的组件,但侧重点不同:
AnnotatedBeanDefinitionReader:主要用于将基于注解的 Bean 定义注册到 Spring 容器中。其主要作用包括:
- 主要通过反射扫描指定的包路径下的类,并识别类上的注解(如 @Component、@Service、@Repository、@Controller 等)。
- 将扫描到的带有注解的类转化为 Spring 的 Bean 定义(BeanDefinition)。
- 将这些 Bean 定义注册到 Spring 容器中,以便后续通过容器获取并管理这些 Bean。
- 常用实现是AnnotationConfigApplicationContext中的AnnotatedBeanDefinitionReader。
ClassPathBeanDefinitionScanner:也用于扫描和注册基于注解的 Bean 定义,但它具有更灵活的配置选项,可以进行更高级的扫描和筛选。其主要作用包括
- 扫描指定包路径下的类,并可以配置扫描过滤器,以筛选出符合特定条件的类。
- 在扫描过程中调用自定义的Bean定义注册器进行注册。
- 默认会扫描@Component等注解,但可自定扫描逻辑。
- 常用实现类是ClassPathBeanDefinitionScanner。
创建AnnotatedBeanDefinitionReader
这里会调用AnnotatedBeanDefinitionReader的有参构造 传入两个参数:BeanDefinitionRegistry,Environment
- BeanDefinitionRegistry-实例为容器本身,即AnnotationConfigApplicationContext
- Environment-实例是StandardEnvironment
/**
* 这里的两个参数一个是容器本身(AnnotationConfigApplicationContext实现了BeanDefinitionRegistry)
* 一个是容器环境-通过代码调用链查看,最后会创建一个 new StandardEnvironment()
*/
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}
private static Environment getOrCreateEnvironment(BeanDefinitionRegistry registry) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
if (registry instanceof EnvironmentCapable) {
return ((EnvironmentCapable) registry).getEnvironment();
}
return new StandardEnvironment();
}
public ConfigurableEnvironment getEnvironment() {
if (this.environment == null) {
this.environment = createEnvironment();
}
return this.environment;
}
protected ConfigurableEnvironment createEnvironment() {
return new StandardEnvironment();
}
有参构造做了三件事:
- 记录bean定义注册器
- 创建条件评估器conditionEvaluator。
- 给bean工厂注册各种后置处理器。
/**
* 创建AnnotatedBeanDefinitionReader 。
* 1.赋值BeanDefinitionRegistry
* 2.创建ConditionEvaluator,记录相关信息
* 3.注册bean的后置处理器
* @param registry 实现类 AnnotationConfigApplicationContext
* @param environment 实现类 StandardEnvironment
*/
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
this.registry = registry;
/*创建ConditionEvaluator,同时创建静态内部类对象ConditionContextImpl给context赋值(主要处理@Conditional注解的判断逻辑。@Conditional注解可以用来有条件地包含或排除配置类和bean的注册。如果指定的条件为true,则该类或bean会被注册,否则会被忽略)
*
* 主要作用记录了spring容器的重要信息为了后面使用:
* 记录bean定义的注册器
* 记录bean工厂是谁
* 记录spring的环境
* 记录当前的资源加载器
* 记录类加载器
* */
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
/*
* 给bean工厂注册各种后置处理器。
* 1.注册了依赖排序器
* 2.注册Autowire候选处理器
* 3.注册配置类后置处理器(spring的bean扫描,解析就是这个处理器完成的)
* 4.注册@Autowire注解的后置处理器,处理@Autowire注解
* 5.注册JSR规范的注解处理器 (@Resource,@PostConstruct,@PreDestroy等注解都是通过此处理器完成)
* 6.注册jpa后置处理器
* 7.注册监听方法的事件监听处理器(查找bean工厂中带有@EventListeners注解的bean的方法放入事件监听器的集合)
* 8.注册事件监听器工厂
* */
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
上述代码中‘bean定义注册器’实际上就是容器本身,再来看看如何创建创建条件评估器conditionEvaluator以及怎么给给bean工厂注册各种后置处理器。
创建conditionEvaluator
/**
* Create a new {@link ConditionEvaluator} instance.
*/
public ConditionEvaluator(@Nullable BeanDefinitionRegistry registry,
@Nullable Environment environment, @Nullable ResourceLoader resourceLoader) {
this.context = new ConditionContextImpl(registry, environment, resourceLoader);
}
/**
* 创建ConditionContextImpl实例。(ConditionContextImpl是@Conditional注解的条件上下文实现类。用于提供条件判断时需要的环境信息)
* 1.设置BeanDefinitionRegistry 实例为AnnotationConfigApplicationContext
* 2.设置ConfigurableListableBeanFactory 实例为DefaultListableBeanFactory 在创建实例AnnotationConfigApplicationContext时 自动创建了实例为DefaultListableBeanFactory实现
* 3.设置Environment 实例为StandardEnvironment
* 4.设置ResourceLoader 实例为DefaultResourceLoader
* 5.设置classLoader 实例为 ClassLoader.getSystemClassLoader(); AppClassLoader
* @param registry 实例为AnnotationConfigApplicationContext
* @param environment 实例为StandardEnvironment
* @param resourceLoader null
*/
public ConditionContextImpl(@Nullable BeanDefinitionRegistry registry,
@Nullable Environment environment, @Nullable ResourceLoader resourceLoader) {
this.registry = registry;
this.beanFactory = deduceBeanFactory(registry);
this.environment = (environment != null ? environment : deduceEnvironment(registry));
this.resourceLoader = (resourceLoader != null ? resourceLoader : deduceResourceLoader(registry));
this.classLoader = deduceClassLoader(resourceLoader, this.beanFactory);
}
给bean工程注册各种后置处理器-AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
/**
* Register all relevant annotation post processors in the given registry.
* @param registry the registry to operate on
*/
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
registerAnnotationConfigProcessors(registry, null);
}
/**
* Register all relevant annotation post processors in the given registry.
* @param registry the registry to operate on
* @param source the configuration source element (already extracted)
* that this registration was triggered from. May be {@code null}.
* @return a Set of BeanDefinitionHolders, containing all bean definitions
* that have actually been registered by this call
* 这个方法主要是根据当前的bean工厂做一些设置:
* 1.添加一个默认的比较器
* 2.设置一个上下文的筛选器(蛀牙对ban的查找进行筛选的类)
* 3.添加ConfigurationClassPostProcessor成一个BeanDefinition;
* 4.添加AutowiredAnnotationBeanPostProcessor成一个BeanDefinition;
* 5.添加CommonAnnotationBeanPostProcessor成一个BeanDefinition;
* 6.添加EventListenerMethodProcessor成一个BeanDefinition;
* 7.添加DefaultEventListenerFactory成一个BeanDefinition;
* 在没有启用JPA的情况下,胡添加5个BeanDefinition(后置处理器),一个比较器BeanDefinition,一个bean筛选器(BeanDefinition)
*/
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
//先得到一个工厂Bean工厂,这个Bean工厂是之前初始化好的,是一个DefaultListableBeanFactory
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
//这里的Bean工厂肯定不能为空,这里是设置比较器的,如果说你没有设置比较器之类的,这里设置一个默认的比较器,这个比较器
//可以在使用BeanDefinition排序的时候使用,比如说你实现了Order接口或者PriorityOrdered的时候,BeanDefinition的执行
//顺序可以使用它来进行排序
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
//这里就是之前我们看的bean中的依赖注入的时候,先byType的时候,对找到的多个bean有筛选,比如先byType,再进行是否启用了
//自动注入候选者,泛型的判断以及Qualifier的筛选
/**
* ContextAnnotationAutowireCandidateResolver中的父类是QualifierAnnotationAutowireCandidateResolver
* QualifierAnnotationAutowireCandidateResolver主要是对泛型的筛选和Qualifier的bean进行筛选,而ContextAnnotationAutowireCandidateResolver
* 是QualifierAnnotationAutowireCandidateResolver它的子类,主要提供了一些代理工厂的创建,延迟加载的一些判断
*/
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
//这里添加一个ConfigurationClass的后置处理器到bd中
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
/**
* 这里添加的是ConfigurationClassPostProcessor这个BeanDefinition,这个BeanDefinition很重要
* 它本身也是一个beanFactory的后置处理器,这里添加进去的意思就是说后面spring启动扫描的时候就是用这个后置处理器来
* 扫描我们的配置类,比如我的配置类是Appconfig,那么这个后置处理器就是专门处理这个配置类配置的类路径信息
* 所以说这个beanFactory后置处理器非常重要,简单来说就是对我们配置类路径进行扫描,扫描成一个一个的BeanDefinition
* 然后放入beanDefinitonMap中,就是这个ConfigurationClassPostProcessor后置处理器来做的事情
*
* 这里生成的是一个RootBeanDefinition,看了spring的生命周期都知道,spring中的扫描成的BeanDefinition最后都会合并成
* RootBeanDefiniton,意思就是它没有父类的bd了
*/
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
//这里添加一个AutowiredAnnotationBeanPostProcessor,这个AutowiredAnnotationBeanPostProcessor在spring的生命周期中
//非常重要,主要是处理依赖注入的@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,这个bean的后置处理器主要处理@Resource、@PostConstruct
* @PreDestory注解,也是依赖注入的一部分,这里先把这个bean的后置处理器加入到beanDefinitionMap中
*/
// 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));
}
// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
//如果你的系统中启用了JPA的方式,那么这里添加一个JPA的后置处理器
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));
}
//事件方法的监听器BeanFactoryPostProcessor,是一个bean工厂的后置处理器
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));
}
//这里添加的是一个默认的事件监听工厂
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;
}
到此spring容器的第一个重要的成员AnnotatedBeanDefinitionReader创建完毕。
- 这里值得关注的一点,注册了ConfigurationClassPostProcessor处理器,在启动过程中这个类很重要。用于处理我们的配置类
创建ClassPathBeanDefinitionScanner
再来看看ClassPathBeanDefinitionScanner是如何创建的,再创建时做了哪些事?看如下调用链
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {
this(registry, true);
}
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) {
this(registry, useDefaultFilters, getOrCreateEnvironment(registry));
}
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
Environment environment) {
this(registry, useDefaultFilters, environment,
(registry instanceof ResourceLoader ? (ResourceLoader) registry : null));
}
/**
* 创建ClassPathBeanDefinitionScanner实例
* 1. 给BeanDefinitionRegistry赋值
* 2. 给父类的includeFilters 添加默认的注解过滤器 @Component
* 3. 给父类的environment 赋值
* 4. 为父类设置资源加载器,三个属性赋值
* ResourcePatternResolver的实例为AnnotationConfigApplicationContext 、
* 创建metadataReaderFactory实例为缓存工厂,内部维护了一个map作为缓存(实例为concurrentMap)
* 赋值componentsIndex 第一次暂时为null
* @param registry AnnotationConfigApplicationContext
* @param useDefaultFilters true
* @param environment StandardEnvironment
* @param resourceLoader AnnotationConfigApplicationContext
*/
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
Environment environment, @Nullable ResourceLoader resourceLoader) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
/*记录bean定义的注册器*/
this.registry = registry;
/*注册三个过滤器,哪些注解要被扫描到:可以自动扫描和处理标注了Spring原生注解@Component以及Java EE注解@ManagedBean、@Named的类
* 1.@Component注解,以及被@Component元注解标记的注解
* 2.JavaEE6的@ManagedBean注解,如果有的话
* 3.JSR-330的@Named注解,如果有的话
* */
if (useDefaultFilters) {
registerDefaultFilters();
}
/*设置扫描环境*/
setEnvironment(environment);
/*
* 设置解析相关资源的处理器
* 这里最主要的就是创建了一个元数据的读取工厂。为后面初始化bean缓存了bean的类以及真是文件信息
* */
setResourceLoader(resourceLoader);
}
调用链最后最后的一个构造方法才是创建ClassPathBeanDefinitionScanner的逻辑。
看看setResourceLoader方法做了哪些事?
/*
* 1.设置资源模式解析器,实际上就是容器本身
* 2.创建一个元数据缓存读取工厂
* 3.componentsIndex=null
* */
@Override
public void setResourceLoader(@Nullable ResourceLoader resourceLoader) {
this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);
/*
* 这里创建一个元数据读取工厂。
* 1.记录了resourceLoader 实际上是容器本身
* 2.记录MetadataReader并创建。,在defaultResourceLoader的resourceCaches中添加了一个MetadataReader为key,value为ConcurrentHashMap。将value作为MetadataReader
* */
this.metadataReaderFactory = new CachingMetadataReaderFactory(resourceLoader);
/*
* 用于加载候选组件索引文件。这个类的主要目的是在 Spring 的组件扫描过程中提高性能,通过索引文件来快速定位候选组件
* */
this.componentsIndex = CandidateComponentsIndexLoader.loadIndex(this.resourcePatternResolver.getClassLoader());
}
@Nullable
public static CandidateComponentsIndex loadIndex(@Nullable ClassLoader classLoader) {
ClassLoader classLoaderToUse = classLoader;
if (classLoaderToUse == null) {
classLoaderToUse = CandidateComponentsIndexLoader.class.getClassLoader();
}
return cache.computeIfAbsent(classLoaderToUse, new Function<ClassLoader, CandidateComponentsIndex>() {
@Override
public CandidateComponentsIndex apply(ClassLoader classLoader1) {
return doLoadIndex(classLoader1);
}
});
}
/**
* 通过遍历所有jar包下的spring.components索引文件,汇总并封装为一个CandidateComponentsIndex对象,供后续组件扫描使用。
*/
@Nullable
private static CandidateComponentsIndex doLoadIndex(ClassLoader classLoader) {
if (shouldIgnoreIndex) {
return null;
}
try {
Enumeration<URL> urls = classLoader.getResources(COMPONENTS_RESOURCE_LOCATION);
if (!urls.hasMoreElements()) {
return null;
}
List<Properties> result = new ArrayList<>();
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
result.add(properties);
}
if (logger.isDebugEnabled()) {
logger.debug("Loaded " + result.size() + " index(es)");
}
int totalCount = result.stream().mapToInt(Properties::size).sum();
return (totalCount > 0 ? new CandidateComponentsIndex(result) : null);
}
catch (IOException ex) {
throw new IllegalStateException("Unable to load indexes from location [" +
COMPONENTS_RESOURCE_LOCATION + "]", ex);
}
}
到此启动容器的第一步已经完成。在这一步中完成了
- 初始化Bean定义的读取器readers和扫描器scanners,用来加载配置类和带注解的类。
- 初始化环境environment的实现,读取环境变量等。
- 初始化事件处理器event multicaster。
- 初始化 SpecificAnnotationAttributeExtractor,用于提取注解的属性值。
- 初始化注解配置缓存annotatedClassesCache。
- 初始化容器的基础设施,如条件评估器conditionEvaluator等。
- 绑定配置中的占位符placeholderConfigurer支持。
等等。
所以this()方法实现了注解驱动Spring容器的基础初始化工作,为后续的注解配置类解析和注解Bean定义注册做好了准备。
注册配置类
register()方法就是通过解析配置类,将其注册为Spring容器内部的Bean定义,为后续实例化Bean做准备。
register()方法的主要逻辑:
- 通过AnnotatedBeanDefinitionReader读取配置类信息,解析组件类上面的注解元数据,生成BeanDefinitionHolder对象。
- 将读取到的BeanDefinitionHolder注册到内部的beanDefinitionMap中,其中key为bean名称,value为BeanDefinition对象。
- 遍历组件类上的注解,提取相关的注解属性并设置到AnnotationConfigUtils.ATTRIBUTES_FROM_COMPONENT_CLASS属性中,保存到后续使用。
- 如果组件类实现了BeanNameGenerator接口,还会设置bean名称生成器。
- 如果组件类实现了ScopeMetadataResolver接口,还会设置作用域元数据解析器。
- 如果组件类实现了ImportAware接口,将处理import相关的配置。
- 最后将配置类Class对象保存到内部集合annotatedClasses中,方便后续处理。
public void register(Class<?>... componentClasses) {
for (Class<?> componentClass : componentClasses) {
registerBean(componentClass);
}
}
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));
//使用上一步加载好的bean定义注解读取器加载我们的配置类
this.reader.register(componentClasses);
registerComponentClass.end();
}
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {
/*创建AnnotatedGenericBeanDefinition实例。目的是将系统中扫描的实例转化为spring的bean(即BeanDefinition) 。
内部记录当前的class
并且创建了一个AnnotationMetadata类型对象(实例为StandardAnnotationMetadata)
实例StandardAnnotationMetadata中记录了目标类的class,创建了一个MergedAnnotations类型对象(实例为TypeMappedAnnotations)
创建MergedAnnotations类型对象的条件:
查找的 AnnotatedElement;
搜索策略 SearchStrategy;
可重复注解容器 RepeatableContainers;
注解过滤器 AnnotationFilter;
*/
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
/*根据 @Conditional 注解判断是否跳过注册*/
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(supplier);
/*解析bean作用域(单例或者原型),如果有@Scope注解,则解析@Scope,没有则默认为单例的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));
// 处理这五个注解:@LazyInit、@Primary、@dependsOn、@role、@description 用户没有赋值则使用默认赋值
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
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));
}
}
}
/*bean的回调处理*/
if (customizers != null) {
for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(abd);
}
}
/*创建一个BeanDefinitionHolder实例,并且持有abd,beanName*/
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
/*是否使用代理模式创建definitionHolder:
* 否:返回原来的definitionHolder
* 是:创建一个新的definitionHolder
* */
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
/*
* 将bean定义注册到bean工厂,如果有别名就注册别名
* */
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
这里就是将我们的配置类转化成bean定义,注册到spring的容器当中。至此spring容器启动过程的第二步已经完成。
以上两步都是准备环境,为了后续初始化容器做准备
刷新容器 refresh()方法
最后一步,也是spring容器启动过程中最重要的一步,是Spring容器启动的关键所在,覆盖了容器从初始化到完成Bean加载的全过程,是容器启动的核心方法。
refresh()方法的主要流程包括:
- 初始化容器前的预处理,如启动时间、active标志等
- 加载Bean定义,通过加载XML、注解等方式解析并注册Bean定义
- 触发BeanFactoryPostProcessor,修改Bean定义元数据
- 注册BeanPostProcessor,用于后续Bean实例化过程中的处理
- 初始化MessageSource,用于国际化消息解析
- 初始化应用事件广播器
- 初始化剩余单例非懒加载Bean,触发完整的Bean生命周期
- 完成refresh,发布容器刷新完成事件
- 注册关闭钩子,以容器关闭时调用销毁方法
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
/*刷新之前的准备动作。
1.记录当前事件
2.将容器变为激活状态
3.初始化程序员实现的自己定义的一些资源
4.验证程序设定的所有必须的属性
5.初始化早期的事件监听器集合,早期的应用事件集合
*/
prepareRefresh();
/*获取容器的bean工厂
*
* 刷新前尝试用cas的方式加锁
* 加锁成功,准备刷新spring容器。
* 然后获取获取容器的bean工厂(工厂实例为DefaultListableBeanFactory),设置该工厂的id
* */
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
/*给工厂添加一些配置:
* 1.添加类加载器
* 2.添加默认的表达式解析器(如果有),属性编辑注册器
* 3.添加两个bean的后置处理器(BeanPostProcessor)。’ApplicationContextAwareProcessor‘, ‘ApplicationListenerDetector’
* 3.处理spring的默认主要接口的默认实现
* 4.向容器的单例池中添加需要的4个单例bean
* 5.忽略默认依赖检查
* */
prepareBeanFactory(beanFactory);
try {
/*空壳方法, 让用户自己实现此方法。
*
* 目的是在spring执行所有的后置处理器之前,留给用户对bean工厂做一些操作。如,添加自己的后置处理器
* 此时还未开始调用bean工厂的后置处理器。bean还未扫描
* */
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// Invoke factory processors registered as beans in the context.
/*
* 开始调用bean工厂的后置处理。这里会执行spring两个内置的后置处理器‘ConfigurationClassPostProcessor’,‘EventListenerMethodProcessor’
*
* ConfigurationClassPostProcessor
* 1.这个处理会扫描并解析我们配置的bean,并封装成BeanDefinitio注入到bean工厂
* 2.执行我们自定义的后置处理器(实现了这两个接口的BeanDefinitionRegistryPostProcessor,BeanFactoryPostProcessor)
* 3.将配置文件类使用cglib生成代理类,并增强
*
* EventListenerMethodProcessor
* 1.收集bean工厂的EventListenerFactory接口,并添加到该处理器内部
* */
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
/*
* 注册bean的后置处理器(该处理器的作用是在bean实例化前后提供处理方法)
* 1.将所有实现了BeanPostProcessor的bean注册到bean工厂
* 2.调整ApplicationListenerDetector处理器到链表的最后
* */
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
/*
* 初始化MessageSource,spring支持国际化信息:
* 1.向容器和单例池中注册messageSource实例
*
* note:根据客户端的语言,返回对应的信息资源。比如做web程序浏览器端用的中文,那么返回中文相关提示,如果是英文则返回英文相关提示
* */
initMessageSource();
/*
* 初始化一个默认的事件发布器。
* 1.向容器和bean工厂的单例池中添加applicationEventMulticaster实例
* */
initApplicationEventMulticaster();
/*
* 空壳方法,留着子类实现,在此时机提供回调。
*
* 目的是在spring刷新时提供回调,让开发者做一些自己的事,如 初始化其他的Bean用的
* 此时,spring的扫描已经完成,但所有的单例还为开始初始化
* */
onRefresh();
/*
* 注册监听器:
* 1.所有实现ApplicationListener接口的监听器
* 将监听器注册到上面的事件发布器当中
* */
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
/*
* 在这里完成bean工厂的初始化!
* 1.创建容器的单例池,在BeanDefinition中如果处于非懒加载的,单例的bean会在这里创建,这里就是spring的bean的生命周期。
* 2.添加字符串解析器
* 3.在实例化单例池之前,先初始化LoadTimeWeaverAware接口的实现类
* */
finishBeanFactoryInitialization(beanFactory);
/*
* 完成刷新。
* 1.发布(触发)容器刷新事件
* 2.清空不需要的缓存,
* 3.添加,调用生命周期处理器,
* 4.处理相应的自定义生命周期接口
* */
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.
destroyBeans();
// Reset 'active' flag.
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...
/*
* 重置缓存,刷新结束
* */
resetCommonCaches();
contextRefresh.end();
}
}
}
prepareRefresh方法
在容器正式启动和加载Bean之前,进行一系列的前置准备和校验工作,为后续的refresh过程做好了初始化,确保了容器可以启动并正常运行
/**
* Prepare this context for refreshing, setting its startup date and
* active flag as well as performing any initialization of property sources.
*
* 设置容器的启动日期startDateTime
* 设置active标志,用于标识容器的激活状态
* 初始化property source abstraction,用于配置属性处理
* 校验必要的属性设置,如环境environment和配置文件路径
* 对系统属性和环境变量进行准备处理
* 对容器内部属性配置的子类做一些准备工作
* 初始化容器内部一些属性,如容器类加载器、事件处理器等
* 校验容器内部属性配置的子类的必要设置
* 存储容器启动阶段的快照,用于容器关闭时显示位标
* 初始化资源路径,如类路径或证书路径等
*/
protected void prepareRefresh() {
//记录当前时间,并且设置AnnotationConfigApplicationContext为活动状态
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());
}
}
//
/*
* 空壳方法,用于程序员定义子类,实现该方法,用于在容器初始化或刷新前,加载一些资源。
*
* */
initPropertySources();
// see ConfigurablePropertyResolver#setRequiredProperties
//验证所有必须的属性是否存在,不存在则抛出异常。验证的系统启动参数,如在系统必须要存在的参数,比如你在-D参数中新增了一个参数bmlxx,那么你需要检查它必须存在
//ac.getEnvironment().setRequiredProperties("bmlxx");
getEnvironment().validateRequiredProperties();
//初始化监听器,如果已有一些监听事件则添加到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<>();
}
prepareBeanFactory方法
obtainFreshBeanFactory()方法是获取bean工厂,没什么好说的。prepareBeanFactory方法是为了给上一步获取到的BeanFactory做各种标准配置,以及添加一些内建处理器,初始化后使其处于可工作状态,为后面完成Bean定义加载与实例化做好准备。
/**
* Configure the factory's standard context characteristics,
* such as the context's ClassLoader and post-processors.
* @param beanFactory the BeanFactory to configure
*
* 设置BeanFactory的class loader为当前context的class loader,方便加载bean类。
* 设置BeanExpressionResolver,用于解析Bean中的表达式语言如#{...}。
* 添加PropertyEditorRegistrar实现,用于属性编辑转换。
* 设置BeanFactory的ResourceLoader,用于加载外部资源文件。
* 设置BeanFactory的ApplicationEventPublisher,用于事件发布。
* 注册一些内建的aware接口,如EnvironmentAware、ResourceLoaderAware等。
* 添加一些BeanPostProcessor实现,如ApplicationContextAwareProcessor等。
* 注册一些内建的scope,如"prototype"和"singleton" 作用域。
* 自定义一些内建bean的名称,如environment、systemProperties等。
* 许多子类会覆盖这个方法定制初始化逻辑。
*/
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
//设置bean工厂的类加载器
beanFactory.setBeanClassLoader(getClassLoader());
//是否使用spring的表达式,如果使用则添加表达式解析器到bean工厂
if (!shouldIgnoreSpel) {
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
}
//添加属性编辑注册器到bean工厂 ,注册器作用未知
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
//添加spring的后置处理器(每次添加都会在集合的末尾),此后置处理器用来实现bean实现aware接口的回调
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//添加需要忽略的依赖检查到HashSet集合
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.ignoreDependencyInterface(ApplicationStartupAware.class);
//添加到resolvableDependencies的集合当中,目的时为了解决注入时一个接口有多个实现,默认自动注入registerResolvableDependency第二个参数的实现
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
//添加spring的后置处理器
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
if (!NativeDetector.inNativeImage() && 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()));
}
//给spring容器注册系统需要的一些单例bean
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());
}
if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
}
}
invokeBeanFactoryPostProcessors方法
该方法的作用是执行BeanFactoryPostProcessor。从字面意思看这个方法就是调用bean工厂的后置处理器,在这里为后续的Bean创建提供了扩展点,允许开发人员对Bean的定义进行干预和修改,以满足特定的需求。例如,可以使用BeanFactory后处理器来动态注入属性值、更改Bean的作用域、创建代理对象等等。
这个方法极其复杂,也是启动过程中非常重要的方法,在这个方法中,完成了我们配置类的扫描,将我们配置的spring的bean扫描到容器中(此时还没有形成bean,以资源的方式存储)
这个方法执行的主要步骤包括:
- 获取所有已注册的BeanFactory后处理器(BeanFactoryPostProcessors)。
- 按照优先级顺序排序这些后处理器(如果它们有优先级)。
- 依次调用每个后处理器的 postProcessBeanFactory() 方法,将BeanFactory作为参数传递给它们。
- 后处理器可以通过修改Bean定义或者执行其他自定义逻辑来影响容器中Bean的配置。
/**
* 这里会将bean工厂后置处理器分成两类:
* a: ’BeanDefinitionRegistryPostProcessors‘
* b: ’BeanFactoryPostProcessor‘
*
* 1.先从参数2中将后置处理器分成上述两类,放到两类集合中。
* 这里如果有a类,就立即执行
* 2.再从bean工厂中先找a类,找到之后再根据排序接口,按序执行。执行顺序@riorityOrdered->Ordered->没有实现排序接口的
* 3.再从bean工厂找b类,根据上述顺序执行
*
* note:从bean工厂中找到的a,b两类,可能没有实例化,这里调用getBean()方法 提前实例化配置类(就是我们的配置文件类)
*
* @param beanFactory bean工厂
* @param beanFactoryPostProcessors 要执行的后置处理器的集合
*/
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// 记录已经处理过的BeanDefinitionRegistryPostProcessors后置处理器
Set<String> processedBeans = new HashSet<>();
/*将spring容器自带的后置处理器分类
* 1.如果实现了BeanDefinitionRegistryPostProcessor接口,那么放到registryProcessors集合,并且立即执行自定义的处理方法
* 2.如果实现了BeanFactoryPostProcessor接口,放到regularPostProcessors集合,暂不执行
* */
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// Separate between BeanDefinitionRegistryPostProcessors that implement
// PriorityOrdered, Ordered, and the rest.
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
/*这里是先调用实现了BeanDefinitionRegistryPostProcessor接口并且实现了PriorityOrdered(排序)接口的后置处理器
1.找到bean工厂中实现了BeanDefinitionRegistryPostProcessor接口的bean名称集合。这里找到的bean是spring容器自带的
2.再遍历是否实现了排序接口,如果实现了就将该bean加入集合,bean名称加入set集合
3.将bean名称加入set集合的目的是防止后置处理器重复执行
*/
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//note:所有配置类(就是我们用来替代xml的文件配置类)会在这里提前初始化,因为调用了beanFactory.getBean()方法
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
//根据指定的排序规则排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
//全部加入之前分类的registryProcessors集合当中
registryProcessors.addAll(currentRegistryProcessors);
/*开始调用BeanDefinitionRegistryPostProcessor类型的后置处理器
* 上面把实现了BeanDefinitionRegistryPostProcessor接口的后置处理器归类,然后在此处集体调用并执行
*
* node:初始化时这里执行的是spring内置的‘配置类后置处理器’ ConfigurationClassPostProcessor。
* 这个配置类会扫描所有我们配置的类,并将bean包装成bean定义(beanDefinition)后注册到bean工厂
* */
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
//处理完成清空集合
currentRegistryProcessors.clear();
/*
* 这里再调用实现了BeanDefinitionRegistryPostProcessor接口但是实现了Ordered(排序)接口的后置处理器,逻辑同上。
*
* node:再次调用beanFactory.getBeanNamesForType获取实现了后置处理的器接口,有可能上面解析时会加入新的后置处理器接口
*
* */
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
//上面可能会获取到已经处理过的处理器,在这过滤掉。 并且该处理器实现了Ordered
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
//最后处理剩下所有的BeanDefinitionRegistryPostProcessors后置处理器,逻辑同上
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
}
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
/*
* 这才开始执行BeanFactoryPostProcessor接口中的postProcessBeanFactory方法。
*
* 1.BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口。
* 2.上面执行完BeanDefinitionRegistryPostProcessor接口时,并没执行BeanFactoryPostProcessor接口内容(是BeanDefinitionRegistryPostProcessor接口的实现类也必定是BeanFactoryPostProcessor的实现类)
* 所以两个集合都需要执行
* 3.再执行BeanFactoryPostProcessor接口中的postProcessBeanFactory方法
*
* node:初始化时,这里也会执行的是spring内置的‘配置类后置处理器’ ConfigurationClassPostProcessor的postProcessBeanFactory方法,会使用cglib生成代理类增强配置类
* */
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
/*
* 这里重新在bean工厂获取BeanFactoryPostProcessor接口的实现类
* 1.因为上面可能执行配置类后置处理器,这个类会扫描系统中的我们配置的bean加入到容器
* */
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
/*
* 在这 将BeanFactoryPostProcessors接口的实现类分成三类,并分别执行
* 1.实现了PriorityOrdered接口的
* 2.实现了Ordered接口
* 3.其他的
* */
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// 空的if代码块,目的是为了过滤掉上面已经处理过的类.下面分三类
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
/*
* 开始调用BeanFactoryPostProcessors的后置处理器,跟上面一样分为三类。
* 先执行PriorityOrdered排序,
* 再执行Ordered排序
* 最后执行没有排序的
* */
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
/*
* 在这里,初始化时这里有一个spring内部的处理器要执行:事件监听方法处理器
* 1.目的是为了初始化该处理器内部的eventListenerFactories属性
* 2.此处理器执行时找到bean工厂的所有EventListenerFactory,然后排序,再赋值到事件监听工厂
* */
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
//后置处理器调用完毕。清除mergedBeanDefinitions,上述处理可能会改变metadata的数据
beanFactory.clearMetadataCache();
}
registerBeanPostProcessors方法
这个方法就是将实现了BeanPostProcessor接口的后置处理器注册到容器当中。在这里分为两类后置处理器,一种是spring的内置处理器,另外一种是开发者自己定义的处理器,按照一定的顺序注册到Spring容器中。
例如处理@PostConstruct,@PreDestroy,@Required等这些注解的处理器
步骤:
- 获取所有已注册的BeanPostProcessor。这些BeanPostProcessor分上述两类。
- 将BeanPostProcessor按照一定的顺序注册到Spring容器中。这个顺序通常由BeanPostProcessor的实现类或配置属性来决定。
- 将注册的BeanPostProcessor添加到容器的BeanPostProcessor列表中,以便在后续的Bean实例化和初始化过程中被调用。
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// WARNING: Although it may appear that the body of this method can be easily
// refactored to avoid the use of multiple loops and multiple lists, the use
// of multiple lists and multiple passes over the names of processors is
// intentional. We must ensure that we honor the contracts for PriorityOrdered
// and Ordered processors. Specifically, we must NOT cause processors to be
// instantiated (via getBean() invocations) or registered in the ApplicationContext
// in the wrong order.
//
// Before submitting a pull request (PR) to change this method, please review the
// list of all declined PRs involving changes to PostProcessorRegistrationDelegate
// to ensure that your proposal does not result in a breaking change:
// https://github.com/spring-projects/spring-framework/issues?q=PostProcessorRegistrationDelegate+is%3Aclosed+label%3A%22status%3A+declined%22
/*
* 查找bean工厂中BeanPostProcessor接口的结合
* */
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
/*
* 将找到的BeanPostProcessor接口的实现类 分成四类。按照分类顺序注册到bean工厂的后置处理器(此容器是一个有序链表)
* 1.实现了PriorityOrdered接口的先注册到最前面
* 2.再注册实现了Ordered接口的
* 3.再注册没有实现上面两个接口的
* 4.在执行上述接口实现类的同时,如果还实现了MergedBeanDefinitionPostProcessor接口,那么会将放入单独的集合,重新注册到链表容器的最后
* */
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, register the BeanPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// Now, register all regular BeanPostProcessors.
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors.
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
/*
* 重新添加ApplicationListenerDetector到bean工厂,目的是为了加到集合的尾部
*
* */
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
initMessageSource方法
初始化国际消息,这个方法的作用就是Spring框架用于支持国际化(i18n)和本地化(l10n)的一个重要组件。它允许应用程序在不同的语言和区域环境下加载不同的消息文本,以提供多语言支持。
/**
* Initialize the MessageSource.
* Use parent's if none defined in this context.
*
* 检查容器中是否已经存在名为 "messageSource" 的Bean。如果已经存在,将其作为消息源。这意味着您可以在Spring配置中自定义消息源,而不是使用默认配置。
*
* 如果容器中没有找到 "messageSource" 的Bean,那么默认情况下,Spring会创建一个 DelegatingMessageSource 类型的Bean作为消息源,并将其注册到容器中。DelegatingMessageSource 是一个复合消息源,它可以包含多个消息源,并按照优先级顺序查找消息。
*
* 设置消息源的父级消息源(Parent Message Source)。这是为了支持消息源的层次结构,允许消息的继承和覆盖。
*
* 初始化消息源的各种属性,如消息源的编码、默认语言等。
*/
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 + "]");
}
}
}
initApplicationEventMulticaster方法
用于初始化应用程序事件多播器(ApplicationEventMulticaster)。应用程序事件多播器是Spring框架中用于处理和传播应用程序事件的关键组件。
一旦初始化完成,它允许应用程序中的各个组件发布事件,同时让其他组件监听并响应这些事件。通常,开发人员可以使用Spring的 ApplicationEventPublisher 接口来发布事件,而事件监听器则会实现 ApplicationListener 接口来监听和处理事件
/**
* Initialize the ApplicationEventMulticaster.
* Uses SimpleApplicationEventMulticaster if none defined in the context.
* @see org.springframework.context.event.SimpleApplicationEventMulticaster
*
*
* 检查容器中是否已经存在名为 "applicationEventMulticaster" 的Bean。如果已经存在,将其作为应用程序事件多播器。这意味着您可以在Spring配置中自定义应用程序事件多播器,而不是使用默认配置。
*
* 如果容器中没有找到 "applicationEventMulticaster" 的Bean,那么默认情况下,Spring会创建一个 SimpleApplicationEventMulticaster 类型的Bean作为应用程序事件多播器,并将其注册到容器中。SimpleApplicationEventMulticaster 是一个简单的多播器,它可以广播事件给所有注册的监听器。
*
* 初始化应用程序事件多播器的各种属性,如执行事件监听器的线程池配置、异常处理策略等。
*/
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() + "]");
}
}
}
registerListeners方法
注册应用程序事件监听器,以便在应用程序中监听和响应事件,实现组件间的通信。这个方法是将监听器注册到上一步的ApplicationEventMulticaster当中,这样就可以监听并响应应用程序中发生的各种事件
/**
* Add beans that implement ApplicationListener as listeners.
* Doesn't affect other listeners, which can be added without being beans.
*
* 从容器中查找所有标注有@EventListener的Bean,注册为应用事件监听器。
* 如果配置了applicationListenerDetector属性,会使用该检测器进一步查找监听器。
* 将查找到的监听器注册到容器的事件广播器中。
* 如果有ApplicationEventMulticaster的bean,则将其设置为事件广播器。
* 最后将已注册的监听器初始化并调用contextRefreshedEvent回调通知
*/
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 (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
finishBeanFactoryInitialization方法
finishBeanFactoryInitialization() 方法是 Spring 容器初始化过程中的最后一步,确保了在容器启动后,所有需要立即可用的 Bean 都已准备就绪
完成单例(Singleton)Bean 的初始化:该方法会遍历容器中所有的 Bean 定义,找到所有需要在容器启动时初始化的单例 Bean,并确保它们被实例化、初始化、依赖注入等。这里就是spring的bean的生命周期。
触发初始化回调方法:对于单例 Bean,Spring 会调用其初始化回调方法(例如,@PostConstruct 方法或实现 InitializingBean 接口的 afterPropertiesSet() 方法)来执行自定义初始化逻辑。
实现懒加载:对于懒加载的单例 Bean,Spring 会根据需要实例化和初始化,而不是在容器启动时。
完成 BeanPostProcessor 的注册和应用:在容器启动后,BeanPostProcessor(Bean 后处理器)会被调用,这些后处理器可以修改 Bean 的配置和行为。
- 触发事件:Spring 可能会在此时触发一些事件,通知监听器容器已经启动完成或某些 Bean 已经初始化完成。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
/*
* 查看bean工厂中是否有一个conversionService的bean,如果有就注册到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 BeanFactoryPostProcessor
// (such as a PropertySourcesPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
/*
* 如果之前没有注册过, 注册一个字符串解析器
* */
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
@Override
public String resolveStringValue(String strVal) {
return AbstractApplicationContext.this.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.
/*
* 修改状态,冻结bean。所有的beanDefinition不会再被修改了,因为马上要实例化了
* */
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
/*
* 实例化剩下的非懒加载的单例bean
* */
beanFactory.preInstantiateSingletons();
}
finishRefresh方法
是Spring 容器刷新过程的最后一步,用于一些扫尾工作,执行一些额外的清理和通知操作,触发容器已经刷新完成的事件、启动生命周期处理器以及完成容器的刷新
protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
/*
* 清除资源缓存。该集合中存在一个元数据读取器,存放我们扫描的bean的类相关数据,类的真实文件信息
*
* */
clearResourceCaches();
/*
* 向容器和单例池中添加一个默认的生命周期处理器
* */
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
/*
* 实现所有的生命周期接口的回调。
* 生命周期接口的扩展,用于哪些需要在ApplicationContext刷新和启动/或按特定顺序关闭时启动的对象
* 保证容器在启动后调用start方法开始生命周期,并且在Spring关闭的时候调用stop方法来结束生命周期,通常用来配置后台程序,比如MQ进行轮询等
* */
getLifecycleProcessor().onRefresh();
/*
* 发布容器刷新事件:
* 1.用户可以自己实现监听器(ApplicationListener),监听这个事件(ContextRefreshedEvent),在容器初始化完成或刷新完成时调用。
* 2.可同步或异步触发
* */
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
if (!NativeDetector.inNativeImage()) {
LiveBeansView.registerApplicationContext(this);
}
}
这一步完成,标志着容器已经准备好接受应用程序的请求,可以正常运行。