spring详解-IOC

Spring--IOC容器

Spring 是一个基于 Java 平台的开源全栈应用程序框架,也是一个控制反转(IoC)容器实现。

Spring IoC 容器即 Spring 框架中负责管理“Bean”(由容器实例化、配置并组装的普通 POJO 对象)的核心组件。容器读取配置元数据(XML、注解或 Java 配置类),解析 Bean 定义,然后在启动或按需时实例化 Bean,完成依赖注入,并负责 Bean 的整个生命周期管理。

本文章示例代码见该仓库:【spring】中的“spring”模块。

仓库地址:https://gitee.com/quercus-sp204/sourcecode-and-demos

1.相关概念

IOC: Inversion of control 【控制反转】

控制反转是一种设计原则,其核心思想是:将程序中对象的创建、配置和生命周期管理的控制权,从应用代码“反转”交给外部框架或容器来负责。在传统的程序设计中,业务逻辑代码主动调用库或框架完成通用功能;而在 IoC 中,则是框架或容器主动调用开发者编写的代码,实现“控制权”反转,此外呢,IoC 不是一种技术,而是一种思想。

降低组件间的耦合度,提升系统的可维护性和扩展性。例如,传统开发中Service层直接依赖Dao层的具体实现,而IoC通过容器动态注入依赖,使两者解耦。

DI:Dependency Injection 【依赖注入】

依赖注入是 IoC 最常见的一种实现方式。在 DI 模式下,对象只需声明它所依赖的其他对象(通过构造器、属性或工厂方法),由 IoC 容器在实例化时自动“注入”这些依赖,从而实现组件间的松耦合和可测试性提升。

在Spring中,我们可以通过构造器注入、Setter方法注入或字段注入(如@Autowired)。

// 构造器注入
@Component
public class UserService {
 private final UserDao userDao;
 @Autowired
 public UserService(UserDao userDao) {
 this.userDao = userDao;
 }
}

2.核心类介绍

我们都知道,spring可以从xml配置文件中解析bean的定义,同时也可以结合相关注解(例如@Configuration, @Bean等)来定义相关bean。最经典的就是这两种了,下面我们就基于这两种类型,来介绍一下相关的核心类。

①基本的

  • Bean工厂相关接口以及context

上面的类间关系图我们需要了解的是红色框框中的三个,BeanFactory、ApplicationEventPublisher、ApplicationContext

BeanFactory : IOC容器的核心接口,定义了基础功能(如getBean()containsBean()),可以看到,BeanFactory是一个顶级接口,定义了比较常用的getBean方法。

public interface BeanFactory {
 String FACTORY_BEAN_PREFIX = "&";
 Object getBean(String name) throws BeansException;
 <T> T getBean(String name, Class<T> requiredType) throws BeansException;
 <T> T getBean(Class<T> requiredType) throws BeansException;
 boolean containsBean(String name);
 .....
}

ApplicationContextBeanFactory的扩展接口,提供高级功能(如国际化、事件发布、AOP支持)

用于为应用程序提供配置的中央接口。这在应用程序运行时是只读的,但如果实现支持,则可以重新加载。ApplicationContext提供:

继承自 ListableBeanFactory用于访问应用程序组件的 Bean 工厂方法。

继承自ResourceLoader 接口用以通用方式加载文件资源的能力。

继承自 ApplicationEventPublisher 接口能够将事件发布到已注册的侦听器。

继承自 MessageSource 接口 能够解析消息的能力,支持国际化。

public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
	MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
 .....
}

ApplicationEventPublisher:封装事件发布功能的接口。

@FunctionalInterface
public interface ApplicationEventPublisher {
 /*
 向在此应用程序注册过应用程序事件的匹配侦听器 发送通知。
 事件可以是框架事件(例如 ContextRefreshedEvent)或特定于应用程序的事件。
 这样的事件发布步骤实际上是移交给 multicaster,并不意味着同步异步执行,甚至根本不意味着立即执行。
 建议事件侦听器尽可能高效,单独使用异步执行来执行运行时间较长且可能阻塞的作。
 */
	default void publishEvent(ApplicationEvent event) {
	publishEvent((Object) event);
	}
 void publishEvent(Object event); // 接口
}

spring各种类非常多,所以在上图中,我这里只做出了各自类之间的大致关系。

DefaultListableBeanFactory: Spring IoC 容器的 基础实现类,直接管理 Bean 的全生命周期(实例化、依赖注入、销毁);通过BeanDefinitionRegistry 接口注册/移除 Bean 定义(如 XML 或注解配置);preInstantiateSingletons() 方法来实例化bean。-----这个方法是实现了接口ConfigurableListableBeanFactory

AbstractApplicationContext:是 容器启动的模板,扩展了企业级功能并依赖 BeanFactory 实现业务逻辑,通过 refresh() 方法定义容器启动流程(如加载配置、注册 BeanFactoryPostProcessor)。在其子类实现中,重写了obtainFreshBeanFactory()方法,可以获取到beanFactory

  • Bean定义

BeanDefinition 接口用于描述一个 Bean 实例的元信息,包括类名、构造函数参数、属性值、作用域、初始化/销毁方法等。

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
 .....
}

BeanDefinitionHolder 封装一个 BeanDefinition 以及它对应的 Bean 名称和别名,可用于内部 Bean 的占位或编程式注册时携带额外信息。

public class BeanDefinitionHolder implements BeanMetadataElement {
	private final BeanDefinition beanDefinition;
	private final String beanName;
	@Nullable
	private final String[] aliases;
 ....
}

BeanDefinitionBuilder 用于以流式 API 构造 GenericBeanDefinitionRootBeanDefinitionChildBeanDefinition 等,并设置各种属性(如 scopelazyInitautowireModeinitMethod 等)。

②基于注解的context

AnnotationConfigApplicationContext :是 Spring 注解驱动配置的核心实现。其中的关键组件:

  • AnnotatedBeanDefinitionReader
    负责解析配置类(@Configuration)并注册 Bean 定义。

    核心逻辑

    • 通过 registerBean() 方法将配置类转换为 AnnotatedGenericBeanDefinition
    • 处理 @Bean 方法,生成对应的 Bean 定义。
    • 注册 BeanPostProcessor(如 ConfigurationClassPostProcessor)。
  • ClassPathBeanDefinitionScanner
    扫描包路径下的类,注册组件(@Component@Service)。

    • 过滤条件:默认扫描带有 @Component 及其派生注解的类。
    • 扩展点:可通过 includeFiltersexcludeFilters 自定义过滤规则。

该context初始化流程

  1. 构造阶段
    • 创建 DefaultListableBeanFactory(底层 BeanFactory)。
    • 初始化 AnnotatedBeanDefinitionReaderClassPathBeanDefinitionScanner
  2. 注册阶段
    • 解析配置类,生成 BeanDefinition(如 AnnotatedGenericBeanDefinition)。
    • 将 Bean 定义注册到 BeanDefinitionRegistry(即 DefaultListableBeanFactory)。
  3. 刷新阶段refresh()):
    • 准备环境:验证配置属性。
    • 获取 BeanFactory:确保 DefaultListableBeanFactory 已初始化。
    • 注册 BeanPostProcessor:如 AutowiredAnnotationBeanPostProcessor
    • 完成 Bean 实例化:通过 preInstantiateSingletons() 预加载单例 Bean。

③基于配置文件的context

ClassPathXmlApplicationContext :

  • 基于 XML 配置的 Spring 容器:通过加载类路径(ClassPath)下的 XML 文件初始化 Spring 容器,管理 Bean 的生命周期和依赖注入。
  • ApplicationContext 的实现类:继承自 AbstractApplicationContext,提供完整的容器功能(如国际化、事件机制)。
  • 传统 Spring 应用的核心入口:适用于 XML 配置驱动的项目(如早期 Spring 项目)。

示例:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
 <bean scope="singleton" class="com.feng.xmlobj.Policeman" name="policeman">
 <constructor-arg name="name" value="国窖001"/>
 </bean>
</beans>
public class XmlContextMain {
 public static void main(String[] args) {
 ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("all-spring.xml");
 Policeman policeman = context.getBean(Policeman.class);
 policeman.say();
 }
}
// 实体类
public class Policeman {
 private String name;
 public Policeman(){
 System.out.println("Policeman 构造函数");
 }
 public Policeman(String name){
 this.name = name;
 }
 public void say() {
 System.out.println(this.name + "报道!");
 }
}

该示例见spring模块中的带有xml前缀的类和包。

现在ClassPathXmlApplicationContext用的很少了,现代 Spring 开发更倾向注解配置。

3. 容器创建

在了解到了基本的类,以及他们之间的大致关系之后,这本节我们来探索一下IOC容器是如何创建的。那我们就以注解配置的context为例子。

ApplicationContext context = new AnnotationConfigApplicationContext(Main.class);
Husband h = context.getBean(Husband.class);
h.say();

从构造函数一步一步向下走

// AnnotationConfigApplicationContext.java
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
 this(); // 1.无参构造
 register(componentClasses); // 2.注册配置类并生成BeanDefinition
 refresh(); // 3.容器刷新
}

①构造函数

// 1.无参构造
public AnnotationConfigApplicationContext() {
 StartupStep createAnnotatedBeanDefReader = getApplicationStartup().start("spring.context.annotated-bean-reader.create");
 // 初始化注解 Bean 定义读取器,通过读取器预注册这些处理器,
 // 以确保后续注解解析和依赖注入的基础能力。
 /*
 创建 AnnotatedBeanDefinitionReader 实例,负责将 
 注解配置类(如 @Configuration、@Component)转换为 BeanDefinition
 自动注册关键组件:
 ConfigurationClassPostProcessor(解析 @Configuration 类)。
 AutowiredAnnotationBeanPostProcessor(处理 @Autowired)。
 CommonAnnotationBeanPostProcessor(处理 @Resource、@PostConstruct)。
 EventListenerMethodProcessor(处理 @EventListener)。
 */
 this.reader = new AnnotatedBeanDefinitionReader(this);
 createAnnotatedBeanDefReader.end();
 /*
 创建 ClassPathBeanDefinitionScanner 实例,负责扫描类路径下的组件类(如 @Component、@Service)
 */
 this.scanner = new ClassPathBeanDefinitionScanner(this);
}

在创建AnnotatedBeanDefinitionReader的时候,默认会创建几个BeanDefinition放到beanDefinitionMap里面。

②注册配置类

// 2.注册配置类并生成BeanDefinition
@Override
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);
 registerComponentClass.end();
}
// AnnotatedBeanDefinitionReader.java
public void register(Class<?>... componentClasses) {
 for (Class<?> componentClass : componentClasses) {
 registerBean(componentClass);
 }
}
// 往下最后是调用下面这个
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
 @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
 @Nullable BeanDefinitionCustomizer[] customizers) {
 // 1.看见没,把Main类封装成了一个BeanDefinition
 AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
 if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
 return;
 }
 // 2.这里就相当于在设置BeanDefinition的属性
 abd.setInstanceSupplier(supplier);
 ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
 abd.setScope(scopeMetadata.getScopeName());
 String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
 AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
 ....
	// 3.注册Bean定义
 BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
 definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
 // 通过 BeanDefinitionReaderUtils 将 BeanDefinitionHolder 
 // 注册到 BeanFactory 的 beanDefinitionMap 中
 BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
// BeanDefinitionReaderUtils.java
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) {
 for (String alias : aliases) {
 registry.registerAlias(beanName, alias);
 }
 }
}
// GenericApplicationContext.java
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
 throws BeanDefinitionStoreException {
 this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
}
// DefaultListableBeanFactory.java
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
 throws BeanDefinitionStoreException {
 .....
 // 1.从缓存beanDefinitionMap中查
 BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
 if (existingDefinition != null) {
 if (!isAllowBeanDefinitionOverriding()) {
 throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
 }
 else if (existingDefinition.getRole() < beanDefinition.getRole()) {
 // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
 ....
 }
 else if (!beanDefinition.equals(existingDefinition)) {
 ....
 }
 else {
 .....
 }
 this.beanDefinitionMap.put(beanName, beanDefinition);
 }
 else { // 2.缓存中没有
 // hasBeanCreationStarted()方法是用来检查此工厂的 bean 创建阶段是否已经开始,
 // 即在此期间是否有任何 bean 被标记为已创建。此时肯定是没有任何bean创建了的
 if (hasBeanCreationStarted()) {
 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 {
 // 放到beanDefinitionMap里面
 this.beanDefinitionMap.put(beanName, beanDefinition);
 this.beanDefinitionNames.add(beanName);
 removeManualSingletonName(beanName);
 }
 this.frozenBeanDefinitionNames = null;
 }
	...
}

这一步把主配置类封装成了一个beanDefinition放进了beanDefinitionMap里面。

③容器刷新【最核心】

refresh()方法是AbstractApplicationContext里面重写的ConfigurableApplicationContext接口的方法。

@Override
public void refresh() throws BeansException, IllegalStateException {
 synchronized (this.startupShutdownMonitor) {
 StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
 // 1. 准备上下文刷新
 prepareRefresh();
 // 2. 获取beanFactory
 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
 // 3. 准备beanFactory,添加一些组件
 prepareBeanFactory(beanFactory);
 try {
 // 4. 子类扩展设置beanFactory
 postProcessBeanFactory(beanFactory);
 StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
 // 5. 执行 BeanFactoryPostProcessor 方法
 invokeBeanFactoryPostProcessors(beanFactory);
 // 6. 注册 BeanPostProcessors
 registerBeanPostProcessors(beanFactory);
 beanPostProcess.end();
 // 7. 初始化 MessageSource 组件,比如做国际化
 initMessageSource();
 // 8. 初始化事件派发器,在注册监听器时会用到
 initApplicationEventMulticaster();
 // 9.【模板方法】子类重写这个方法,在容器刷新的时候可以自定义逻辑-
 // 例如Servlet的容器,里面会启动嵌入的tomcat
 onRefresh();
 //10.注册监听器
 registerListeners();
 // 11. 创建所有的bean,并且初始化 【最核心的一个方法】
 finishBeanFactoryInitialization(beanFactory);
 // 12.容器刷新完成,发布一个事件
 finishRefresh();
 }
 catch (BeansException ex) {
 // 出现异常的步骤-这里就不看了
 }
 finally {
 
 resetCommonCaches();
 contextRefresh.end();
 }
 }
}

可以看到,这个方法巨长,里面调用了十几个方法。加个锁确保安全性,就没啥好解释的了。。。上面有十几个步骤,其中一些不是很重要的我这里就不去分析了,仅做一个简要介绍

准备上下文刷新

刷新前的预处理,设置容器状态并初始化环境。设置 active=true(容器激活)、closed=false

初始化环境变量(Environment),校验必填属性(如数据库 URL)

protected void prepareRefresh() {
 // Switch to active.
 this.startupDate = System.currentTimeMillis();
 this.closed.set(false);
 this.active.set(true);
	..
 // Initialize any placeholder property sources in the context environment.
 initPropertySources();
 // Validate that all properties marked as required are resolvable:
 // see ConfigurablePropertyResolver#setRequiredProperties
 getEnvironment().validateRequiredProperties();
 ....
}

获取beanFactory

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
 refreshBeanFactory();
 return getBeanFactory();
}

返回的是DefaultListableBeanFactory类型的bean工厂

准备beanFactory

BeanFactory 添加通用组件和配置;设置类加载器(ClassLoader);注册 BeanPostProcessor(如 ApplicationContextAwareProcessor);忽略特定接口的自动装配(如 ServletContextAware)。

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	...
	beanFactory.setBeanClassLoader(getClassLoader());
	...
	// 注册BeanPostProcessor
	beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
	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);
	// Register early post-processor for detecting inner beans as ApplicationListeners.
	beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
	..
	}

子类扩展设置beanFactory

子类扩展点,用于对 BeanFactory 进行后置处理。比如说,Web 环境中注册 ServletContext 作用域;动态注册自定义的 BeanDefinition

执行 BeanFactoryPostProcessor 方法

​ 执行 BeanFactoryPostProcessor,修改 BeanDefinition,也就是说可以用 BeanFactoryPostProcessor 来定制配置的元数据。这个接口的语义与 BeanPostProcessor 相似,但有一个主要区别: BeanFactoryPostProcessor 在 Bean 配置元数据上运行。也就是说,Spring IoC 容器允许 BeanFactoryPostProcessor 在容器实例化任何 Bean(BeanFactoryPostProcessor 实例除外)之前读取配置元数据并进行可能的更改。在这里我们只先知道BeanPostProcessorBeanFactoryPostProcessor这两个接口就行了,在后面做具体分析。

​ 通过查阅spring官方文档得知: 我们可以配置多个 BeanFactoryPostProcessor 实例,并可通过设置 order 属性来控制这些 BeanFactoryPostProcessor 实例的运行顺序。但是,只有当 BeanFactoryPostProcessor 实现了 Ordered 接口时,才能设置该属性。

​ invokeBeanFactoryPostProcessors里面大致可以分为两部分:

1. 处理BeanDefinitionRegistryPostProcessor:优先处理BeanDefinitionRegistryPostProcessor,允许动态注册Bean定义(如@Configuration类解析)。例如ConfigurationClassPostProcessor,这个就会解析加了@Configuration的配置类,还会解析@ComponentScan、@ComponentScans注解扫描的包,以及解析@Import等注解。
2. 处理BeanFactoryPostProcessor:处理BeanFactoryPostProcessor,仅修改现有Bean定义(如PropertySourcesPlaceholderConfigurer解析占位符)
// AbstractApplicationContext.java
//在Bean实例化之前执行,确保所有'Bean定义'已被后置处理器处理完毕
invokeBeanFactoryPostProcessors(beanFactory);
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
 //委托给PostProcessorRegistrationDelegate执行所有后置处理器
 // getBeanFactoryPostProcessors()返回上下文配置中显式注册的BeanFactoryPostProcessor
 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 (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null &&
 beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
 beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
 beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
 }
}
// PostProcessorRegistrationDelegate.java
// 这个方法巨长无比
public static void invokeBeanFactoryPostProcessors(
	ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
 
 // invokeBeanDefinitionRegistryPostProcessors部分
 // 解析容器中其他的BeanDefinition,放到eanDefinitionMap里面
 // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
 
 // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
 ..... 
 // 最后一部分
 // 执行普通BeanFactoryPostProcessor
 // 实现了PriorityOrdered的
 // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
 sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
 invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); //=====
 // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
 // 实现了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); //=====
 // 最普通的
 // Finally, invoke all other BeanFactoryPostProcessors.
 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...
 beanFactory.clearMetadataCache();
}
private static void invokeBeanFactoryPostProcessors(
 Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
 for (BeanFactoryPostProcessor postProcessor : postProcessors) {
 StartupStep postProcessBeanFactory = beanFactory.getApplicationStartup().start("spring.context.bean-factory.post-process").tag("postProcessor", postProcessor::toString);
 postProcessor.postProcessBeanFactory(beanFactory); // 调用方法
 postProcessBeanFactory.end();
 }
}

如下示例使用:

@Configuration
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
 @Override
 public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
 BeanDefinition husband = beanFactory.getBeanDefinition("husband");
 System.out.println(husband);
 }
}

注册 BeanPostProcessors

registerBeanPostProcessors 方法的主要功能是注册所有的 BeanPostProcessor 类型的 bean。

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
 PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

实际逻辑由 PostProcessorRegistrationDelegate 类的静态方法 registerBeanPostProcessors 处理, 将容器中所有 BeanPostProcessor 实例注册到 BeanFactory,以便后续 Bean 初始化时调用。

BeanFactoryPostProcessor,也分先后顺序:

​ 1.PriorityOrdered:最高优先级(如 BeanValidationPostProcessor)。

​ 2.Ordered:次高优先级(通过 @Order 注解或实现 Ordered 接口)。

​ 3.普通:无顺序要求。

初始化 MessageSource 组件

用于初始化国际化(i18n)相关的消息源(MessageSource

初始化事件派发器

initApplicationEventMulticaster()

主要作用是初始化应用程序事件多播器ApplicationEventMulticaster)。事件多播器的功能是把应用程序事件(ApplicationEvent)广播给所有注册的事件监听器(ApplicationListener)。

举个例子:【见仓库中的 event 包】

public class HelloEvent extends ApplicationEvent { // 定义一个事件
 private String message;
 public HelloEvent(Object source, String message) { // 第一个参数必须是source
 super(source);
 this.message = message;
 }
 public String getMessage() {
 return message;
 }
}
// 事件发布
@Component(value = "helloEventPublisher")
public class HelloEventPublisher {
 @Autowired
 private ApplicationEventPublisher publisher;
 public void publishEvent(String msg) {
 HelloEvent event = new HelloEvent(this, msg);
 publisher.publishEvent(event);
 }
}
// 监听器1
// 基于注解(支持异步+条件)
@Component
public class HelloEventListener {
 // 需要开启异步支持
 // @Async
 // @EventListener
 public void handleEvent(HelloEvent helloEvent) {
 System.out.println("【(异步方式)事件监听到了:】" + helloEvent.getMessage());
 try {
 Thread.sleep(1000);
 System.out.println("【(异步方式)事件监听结束了】");
 } catch (InterruptedException e) {
 throw new RuntimeException(e);
 }
 }
 // 条件监听(仅处理特定用户)
 @EventListener(condition = "#event.message.endsWith('-VIP')")
 public void vipNotification(HelloEvent event) {
 System.out.println("VIP事件 " + event.getMessage() );
 }
}
// 监听器2
//基于接口(同步监听)
// @Component
public class InterfaceHelloEventListener implements ApplicationListener<HelloEvent> {
 @Override
 public void onApplicationEvent(HelloEvent event) {
 System.out.println("【基于接口的方式-listener】" + event.getMessage());
 }
}

那么,如下场景我们可以考虑用事件发布监听的方式来实现。

  1. 电商系统
    • 用户下单 → 发布 OrderCreatedEvent
    • 监听器:库存扣减、优惠券核销、支付回调
  2. 社交平台
    • 用户发帖 → 发布 PostCreatedEvent
    • 监听器:内容审核、推荐算法触发、消息推送
  3. 微服务架构
    • 服务A完成操作 → 发布领域事件
    • 服务B通过消息队列中间件订阅事件实现最终一致性

自定义逻辑

onRefresh();【模板方法的设计模式】

举个例子:比如说我们的SpringBoot应用,假如开启了web支持,在其子类中,会重写该方法。

// ServletWebServerApplicationContext.java
@Override
protected void onRefresh() {
 super.onRefresh();
 try {
 createWebServer(); // 创建内嵌Tomcat容器
 }
 catch (Throwable ex) {
 throw new ApplicationContextException("Unable to start web server", ex);
 }
}

注册监听器

将监听器注册到事件广播器(ApplicationEventMulticaster)中,并触发早期事件的广播。

protected void registerListeners() {
 // 注册静态监听器
 // 1.getApplicationListeners返回在 Spring 容器初始化前通过编程方式手动注册的监听器
 //(例如在配置类中直接添加的监听器)。
 for (ApplicationListener<?> listener : getApplicationListeners()) {
 getApplicationEventMulticaster().addApplicationListener(listener);
 }
 // 2. 注册 Bean 定义的监听器
 // 获取所有实现了 ApplicationListener 接口的 Bean 名称(不实例化 Bean,仅获取名称)
 String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
 for (String listenerBeanName : listenerBeanNames) {
 // 通过 Bean 名称注册监听器,延迟到事件触发时才获取 Bean 实例
 getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
 }
 // Publish early application events now that we finally have a multicaster...
 // 3.发布早期事件
 Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
 this.earlyApplicationEvents = null;
 if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
 for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
 getApplicationEventMulticaster().multicastEvent(earlyEvent);
 }
 }
}

实例所有的bean **【important】

// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);

最核心的步骤了,我们顺着这个方法,一直往下,可以发现到达了这里。

// AbstractApplicationContext.java
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
// 实际上是DefaultListableBeanFactory.java 是 BeanFactory的子类实现
@Override
public void preInstantiateSingletons() throws BeansException {
 List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
 //实例化非延迟单例Bean
 for (String beanName : beanNames) {
 RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
 // 处理FactoryBean和非FactoryBean
 if (isFactoryBean(beanName)) { // 工厂Bean特殊处理
 Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
 .....
 }
 // 触发普通Bean的实例化与初始化【重点关注的是这个】
 else {
 /*
 getBean()会触发Bean的实例化、依赖注入、@PostConstruct方法、
 InitializingBean.afterPropertiesSet()等初始化逻辑
 */
 getBean(beanName);
 }
 }
 }
 for (String beanName : beanNames) {
 Object singletonInstance = getSingleton(beanName);
 // 触发SmartInitializingSingleton回调
 if (singletonInstance instanceof SmartInitializingSingleton) {
 StartupStep smartInitialize = getApplicationStartup().start("spring.beans.smart-initialize")
 .tag("beanName", beanName);
 SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
 ...
 smartSingleton.afterSingletonsInstantiated();
 ...
 smartInitialize.end();
 }
 }
}

也就是说上面的方法可以分为两个部分: 1.实例化所有非Lazy的bean;2.触发SmartInitializingSingleton回调,也就是说,SmartInitializingSingleton接口的afterSingletonsInstantiated()方法在所有单例Bean实例化完成后执行。

SmartInitializingSingleton阶段,我们可以做什么呢?举个简单的例子:缓存预热嘛,是吧

@Component
public class CacheWarmupBean implements SmartInitializingSingleton {
 @Autowired
 private CacheManager cacheManager;
 @Override
 public void afterSingletonsInstantiated() {
 cacheManager.getCache("userCache").putAll(loadInitialData());
 }
}

那么,我们重点关注第一个部分中的普通bean的实例化和初始化getBean(beanName)

// AbstractBeanFactory.java
@Override
public Object getBean(String name) throws BeansException {
 return doGetBean(name, null, null, false);
}
protected <T> T doGetBean(
 String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
 throws BeansException {
 // 这个里面只给出关键部分
 // 1.检查单例缓存
 /*
 此步骤会先从单例 Bean 缓存中查找指定名称的 Bean 实例。
 Spring 使用三级缓存机制来管理单例 Bean,这里会尝试从一级缓存(singletonObjects)、
 二级缓存(earlySingletonObjects)和
 三级缓存(singletonFactories)中获取 Bean 实例
 */
 // Eagerly check singleton cache for manually registered singletons.
	Object sharedInstance = getSingleton(beanName);
 ...
 
 //3.保证当前 Bean 所依赖的 bean 的初始化。
 String[] dependsOn = mbd.getDependsOn();
 if (dependsOn != null) {
	.....
 }
 
 //4.Create bean instance.
 //4.1 创建单例bean【重点】
 if (mbd.isSingleton()) {
 sharedInstance = getSingleton(beanName, () -> {
 try {
 return createBean(beanName, mbd, args);
 }
 ....
 });
 beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
 }
 //4.2 创建原型bean
 //4.3 其他
}

可以看到上面的方法大致分为了4步,

首先检查缓存getSingleton(beanName)本质往下面是调用了DefaultSingletonBeanRegistry的protected Object getSingleton(String beanName, boolean allowEarlyReference) 方法。

第二步,合并 Bean 定义:解析父类或父容器的 Bean 定义(支持继承) ---- 这个不是很重要,问的gpt:合并Bean定义的核心目的是实现配置的继承与复用,通过将父Bean的公共配置与子Bean的个性化配置结合,提高代码的可维护性和灵活性】

第三步,检查依赖关系【@DependsOn注解】,若 Bean 有依赖的其他 Bean,会先递归获取这些依赖的 Bean 实例,同时检查是否存在循环依赖。

最后一步就是创建bean了,这里只关注单例bean的创建,调用了重载的方法public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory),第二个参数是一个函数式接口,即对象工厂,里面的getObject()方法就是调用的lambda表达式里面的逻辑如下。

() -> {
 try {
 return createBean(beanName, mbd, args);
 }....
}

搞清楚了这层关系,那我们就来看重载的getSingleton方法

// DefaultSingletonBeanRegistry.java
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
 ...
 synchronized (this.singletonObjects) {
 Object singletonObject = this.singletonObjects.get(beanName);
 if (singletonObject == null) {
 ...
 beforeSingletonCreation(beanName);
 boolean newSingleton = false;
 boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
 if (recordSuppressedExceptions) {
 this.suppressedExceptions = new LinkedHashSet<>();
 }
 try {
 // 这一步是调用的上面lambda表达式的createBean(beanName, mbd, args);
 singletonObject = singletonFactory.getObject(); 
 newSingleton = true;
 }
 catch (IllegalStateException ex) {
 .....
 }
 catch (BeanCreationException ex) {
 .....
 }
 finally {
 if (recordSuppressedExceptions) {
 this.suppressedExceptions = null;
 }
 afterSingletonCreation(beanName);
 }
 if (newSingleton) {
 // 放入单例池,删除二三级缓存
 addSingleton(beanName, singletonObject);
 }
 }
 return singletonObject;
 }
}
// lambda表达式的createBean(beanName, mbd, args);
// AbstractAutowireCapableBeanFactory.java
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
 throws BeanCreationException {
 .....
 try {
 Object beanInstance = doCreateBean(beanName, mbdToUse, args);
 ......
 return beanInstance;
 }
 ....
}
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
 throws BeanCreationException {
 // 1. 实例化bean
 BeanWrapper instanceWrapper = null;
 if (mbd.isSingleton()) {
 instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
 }
 if (instanceWrapper == null) {
 instanceWrapper = createBeanInstance(beanName, mbd, args);
 }
 Object bean = instanceWrapper.getWrappedInstance();
 Class<?> beanType = instanceWrapper.getWrappedClass();
 if (beanType != NullBean.class) {
 mbd.resolvedTargetType = beanType;
 }
 // Allow post-processors to modify the merged bean definition.
 ....
 // 缓存早期单例,以便能够解析循环引用
 boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
 isSingletonCurrentlyInCreation(beanName));
 if (earlySingletonExposure) {
 if (logger.isTraceEnabled()) {
 ...
 }
 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
 }
 // 初始化bean
 Object exposedObject = bean;
 try {
 // 依赖注入:属性填充
 populateBean(beanName, mbd, instanceWrapper);
 // 执行初始化方法
 exposedObject = initializeBean(beanName, exposedObject, mbd);
 }
 catch (Throwable ex) {
 ...
 }
 /*
 是在 Bean 创建完成后,检查并处理该 Bean 的早期单例引用。
 如果存在早期单例引用,会根据具体情况对最终暴露的 Bean 对象进行调整,
 以确保在循环依赖的场景下,依赖该 Bean 的其他 Bean 使用的是正确版本的 Bean 实例。
 就是确保最终所有依赖都指向完全初始化的Bean
 */
 if (earlySingletonExposure) {
 Object earlySingletonReference = getSingleton(beanName, false);
 if (earlySingletonReference != null) {
 if (exposedObject == bean) {
 exposedObject = earlySingletonReference;
 }
 else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
 String[] dependentBeans = getDependentBeans(beanName);
 Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
 for (String dependentBean : dependentBeans) {
 if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
 actualDependentBeans.add(dependentBean);
 }
 }
 ..
 }
 }
 }
 // Register bean as disposable.
 try {
 registerDisposableBeanIfNecessary(beanName, bean, mbd);
 }
 catch (BeanDefinitionValidationException ex) {
 ...
 }
 return exposedObject;
}

了解了上面的代码结构,我们可以理清楚如下思路。

从上图我们可以看出,bean的创建和初始化等操作,都是在createBean中完成的。

populateBean(beanName, mbd, instanceWrapper):属性填充

populateBean 是 Spring 框架中用于填充 Bean 属性的核心方法,负责将 Bean 定义中的属性值(如依赖注入、配置值等)注入到 Bean 实例中。它是 Bean 生命周期中实例化后、初始化前的关键步骤,属于 AbstractAutowireCapableBeanFactory 类的一部分,属性注入完成后,才会执行 @PostConstructInitializingBean.afterPropertiesSet()

@Autowired@Resource 注解的解析是在调用 InstantiationAwareBeanPostProcessorpostProcessProperties 方法时完成的。具体来说,Spring 提供了 AutowiredAnnotationBeanPostProcessor 来处理 @Autowired 注解,CommonAnnotationBeanPostProcessor 来处理 @Resource 注解。

当执行到 InstantiationAwareBeanPostProcessorpostProcessProperties 方法时,AutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessor 会扫描 Bean 类的字段、方法和构造函数,查找带有 @Autowired@Resource 注解的元素,然后根据注解的配置进行依赖注入。

// 属性填充大致可以划分为两部分
//1.postProcessAfterInstantiation
//这里会遍历所有实现了 InstantiationAwareBeanPostProcessor 接口的后置处理器,调用它们的 postProcessAfterInstantiation 方法
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
 for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
 if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
 return;
 }
 }
}
//2.postProcessProperties【@Autowired 和 @Resource 解析】 && postProcessPropertyValues
//再次遍历所有实现了 InstantiationAwareBeanPostProcessor 接口的后置处理器,调用它们的 postProcessProperties 方法。
//若该方法返回 null,则进一步调用 postProcessPropertyValues 方法。
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
 PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
 if (pvsToUse == null) {
 ....
 pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
 ...
 }
 pvs = pvsToUse;
}

initializeBean(beanName, exposedObject, mbd) : bean初始化

initializeBean 是 Spring 框架中 Bean 生命周期管理的核心方法,负责执行 Bean 的初始化阶段。它在 Bean 实例化、属性填充后触发,确保 Bean 完成最终的配置和初始化逻辑。

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
 ...
 // 1.处理 Aware 接口回调
 	invokeAwareMethods(beanName, bean);
 Object wrappedBean = bean;
 if (mbd == null || !mbd.isSynthetic()) {
 // 2.应用 BeanPostProcessor 的前置处理方法
 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
 }
 try {
 // 3. 调用 Bean 的初始化方法
 invokeInitMethods(beanName, wrappedBean, mbd);
 }
 catch (Throwable ex) {
 throw new BeanCreationException(
 (mbd != null ? mbd.getResourceDescription() : null),
 beanName, "Invocation of init method failed", ex);
 }
 if (mbd == null || !mbd.isSynthetic()) {
 // 4.应用 BeanPostProcessor 的后置处理方法【可能会生成代理对象】
 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
 }
 return wrappedBean;
}

可以看到bean初始化有大致四个步骤:

  1. 如果 Bean 实现了 BeanNameAwareBeanFactoryAware 等 Aware 接口,调用对应方法

  2. 遍历所有 BeanPostProcessor,调用 postProcessBeforeInitialization

  3. 调用 Bean 的初始化方法:@PostConstruct 注解的方法InitializingBean.afterPropertiesSet()XML 配置的 init-method

  4. 对初始化后的 Bean 进一步处理(如生成 AOP 代理

在调试的时候,我们发现在applyBeanPostProcessorsAfterInitialization()方法中出现了如下所示:

执行了AnnotationAwareAspectJAutoProxyCreator类 :: postProcessAfterInitialization() 方法。 它是 Spring AOP 的核心组件之一,负责根据注解(如 @Aspect@Before)动态生成 AOP 代理。也就是说,Spring IOC 容器创建 bean 实例时,最后都会对 bean 进行处理,来实现增强。对于 Spring AOP 来说,就是创建代理类。 【见后续文章 SpringAOP】

容器刷新完成

protected void finishRefresh() {
 // 清除上下文级资源缓存(例如扫描中的 ASM 元数据)-- 不了解
 clearResourceCaches();
 // 为此上下文初始化生命周期处理器。
 initLifecycleProcessor();
 // Propagate refresh to lifecycle processor first.
 getLifecycleProcessor().onRefresh();
 // 发布一个ContextRefreshedEvent事件 -- 
 // 这个可以了解一下【上面也介绍到了事件event】
 publishEvent(new ContextRefreshedEvent(this));
 // Participate in LiveBeansView MBean, if active.
 if (!NativeDetector.inNativeImage()) {
 LiveBeansView.registerApplicationContext(this);
 }
}

负责完成应用上下文刷新的最后阶段,

end.参考

  1. https://blog.csdn.net/xiaofeng10330111/article/details/85253251 【csdn--张彦峰ZYF--理解IOC与DI】
  2. https://blog.csdn.net/ivan820819/article/details/79744797 【csdn--ivan820819--浅谈IOC--说清楚IOC是什么】
  3. https://segmentfault.com/a/1190000038438265最简 Spring AOP 源码分析!
作者:别来无恙✲原文地址:https://www.cnblogs.com/jackjavacpp/p/18829545

%s 个评论

要回复文章请先登录注册