您的位置:首页 > 科技 > 能源 > 策划书word模板_湖州网站建设官网_企业网站seo服务_sem竞价广告

策划书word模板_湖州网站建设官网_企业网站seo服务_sem竞价广告

2025/4/19 16:14:01 来源:https://blog.csdn.net/okok__TXF/article/details/147285599  浏览:    关键词:策划书word模板_湖州网站建设官网_企业网站seo服务_sem竞价广告
策划书word模板_湖州网站建设官网_企业网站seo服务_sem竞价广告

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;@Autowiredpublic 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;@Nullableprivate 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.注册配置类并生成BeanDefinitionrefresh(); // 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类封装成了一个BeanDefinitionAnnotatedGenericBeanDefinition 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. 获取beanFactoryConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// 3. 准备beanFactory,添加一些组件prepareBeanFactory(beanFactory);try {// 4. 子类扩展设置beanFactorypostProcessBeanFactory(beanFactory);StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");// 5. 执行 BeanFactoryPostProcessor 方法invokeBeanFactoryPostProcessors(beanFactory);// 6. 注册 BeanPostProcessorsregisterBeanPostProcessors(beanFactory);beanPostProcess.end();// 7. 初始化 MessageSource 组件,比如做国际化initMessageSource();// 8. 初始化事件派发器,在注册监听器时会用到initApplicationEventMulticaster();// 9.【模板方法】子类重写这个方法,在容器刷新的时候可以自定义逻辑-// 例如Servlet的容器,里面会启动嵌入的tomcatonRefresh();//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#setRequiredPropertiesgetEnvironment().validateRequiredProperties();....
}
获取beanFactory
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {refreshBeanFactory();return getBeanFactory();
}

返回的是DefaultListableBeanFactory类型的bean工厂

准备beanFactory

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

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {...beanFactory.setBeanClassLoader(getClassLoader());...// 注册BeanPostProcessorbeanFactory.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()返回上下文配置中显式注册的BeanFactoryPostProcessorPostProcessorRegistrationDelegate.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 {@Overridepublic 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) { // 第一个参数必须是sourcesuper(source);this.message = message;}public String getMessage() {return message;}
}
// 事件发布
@Component(value = "helloEventPublisher")
public class HelloEventPublisher {@Autowiredprivate ApplicationEventPublisher publisher;public void publishEvent(String msg) {HelloEvent event = new HelloEvent(this, msg);publisher.publishEvent(event);}
}
// 监听器1
// 基于注解(支持异步+条件)
@Component
public class HelloEventListener {// 需要开启异步支持// @Async// @EventListenerpublic 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> {@Overridepublic 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);//实例化非延迟单例Beanfor (String beanName : beanNames) {RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {// 处理FactoryBean和非FactoryBeanif (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 {@Autowiredprivate CacheManager cacheManager;@Overridepublic 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. 实例化beanBeanWrapper 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));}// 初始化beanObject 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 源码分析!】

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com