[db:标题]

摘要:Spring--IOC容器 Spring 是一个基于 Java 平台的开源全栈应用程序框架,也是一个控制反转(IoC)容器实现。 Spring IoC 容器即 Spring 框架中负责管理“Bean”(由容器实例化、配置并组装的普通 POJ
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); ..... } ApplicationContext:BeanFactory的扩展接口,提供高级功能(如国际化、事件发布、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 构造 GenericBeanDefinition、RootBeanDefinition、ChildBeanDefinition 等,并设置各种属性(如 scope、lazyInit、autowireMode、initMethod 等)。 ②基于注解的context AnnotationConfigApplicationContext :是 Spring 注解驱动配置的核心实现。其中的关键组件: AnnotatedBeanDefinitionReader 负责解析配置类(@Configuration)并注册 Bean 定义。 核心逻辑 通过 registerBean() 方法将配置类转换为 AnnotatedGenericBeanDefinition。 处理 @Bean 方法,生成对应的 Bean 定义。 注册 BeanPostProcessor(如 ConfigurationClassPostProcessor)。 ClassPathBeanDefinitionScanner 扫描包路径下的类,注册组件(@Component、@Service)。 过滤条件:默认扫描带有 @Component 及其派生注解的类。 扩展点:可通过 includeFilters 和 excludeFilters 自定义过滤规则。 该context初始化流程 构造阶段: 创建 DefaultListableBeanFactory(底层 BeanFactory)。 初始化 AnnotatedBeanDefinitionReader 和 ClassPathBeanDefinitionScanner。 注册阶段: 解析配置类,生成 BeanDefinition(如 AnnotatedGenericBeanDefinition)。 将 Bean 定义注册到 BeanDefinitionRegistry(即 DefaultListableBeanFactory)。 刷新阶段(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 实例除外)之前读取配置元数据并进行可能的更改。在这里我们只先知道BeanPostProcessor和 BeanFactoryPostProcessor这两个接口就行了,在后面做具体分析。 ​ 通过查阅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()); } } 那么,如下场景我们可以考虑用事件发布监听的方式来实现。 电商系统 用户下单 → 发布 OrderCreatedEvent 监听器:库存扣减、优惠券核销、支付回调 社交平台 用户发帖 → 发布 PostCreatedEvent 监听器:内容审核、推荐算法触发、消息推送 微服务架构 服务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 类的一部分,属性注入完成后,才会执行 @PostConstruct 或 InitializingBean.afterPropertiesSet()。 @Autowired 和 @Resource 注解的解析是在调用 InstantiationAwareBeanPostProcessor 的 postProcessProperties 方法时完成的。具体来说,Spring 提供了 AutowiredAnnotationBeanPostProcessor 来处理 @Autowired 注解,CommonAnnotationBeanPostProcessor 来处理 @Resource 注解。 当执行到 InstantiationAwareBeanPostProcessor 的 postProcessProperties 方法时,AutowiredAnnotationBeanPostProcessor 和 CommonAnnotationBeanPostProcessor 会扫描 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初始化有大致四个步骤: 如果 Bean 实现了 BeanNameAware、BeanFactoryAware 等 Aware 接口,调用对应方法 遍历所有 BeanPostProcessor,调用 postProcessBeforeInitialization 调用 Bean 的初始化方法:@PostConstruct 注解的方法;InitializingBean.afterPropertiesSet();XML 配置的 init-method 对初始化后的 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.参考 https://blog.csdn.net/xiaofeng10330111/article/details/85253251 【csdn--张彦峰ZYF--理解IOC与DI】 https://blog.csdn.net/ivan820819/article/details/79744797 【csdn--ivan820819--浅谈IOC--说清楚IOC是什么】 https://segmentfault.com/a/1190000038438265 【最简 Spring AOP 源码分析!】