--- title: Spring IOC简介 date: 2025-11-26 --- # 一、IOC   Spring框架的核心是IOC(控制反转)容器,它负责管理应用程序中的对象(称为Bean)的创建、配置和组装。   [IoC 容器](https://docs.springjava.cn/spring-framework/reference/core/beans.html) # 二、Bean ## 2.1 定义   在Spring中,Bean是指由Spring IOC容器管理的对象实例。这些对象不再由应用程序直接创建,而是由容器负责实例化、配置和组装。   例如@Service、@Controller就是特殊的Bean。 ## 2.2 特点 - 由容器管理:生命周期由Spring容器控制 - 可配置性:通过配置元数据定义Bean的行为 - 依赖注入:容器自动处理Bean之间的依赖关系 - 作用域支持:支持singleton、prototype等不同作用域 ## 2.3 创建方式 ```java // 1. 通过@Component注解 @Component public class UserService { // ... } // 2. 通过@Bean注解(配置类中) @Configuration public class AppConfig { @Bean public DataSource dataSource() { return new DataSource(); } } // 3. 通过XML配置 ``` ::: tip @Service、@Controller这些注解是@Component的衍生注解。 @Component注解可以通过@Autowired自动注入,一般用于自己编写的业务模块,需要配合@ComponentScan启用组件扫描(实际开发中@SpringBootApplication注解已经包含了@ComponentScan注解)。 @Bean注解一般用于注册第三方库的类。 ::: ## 2.4 作用域   控制 Bean 在容器中的实例数量和生命周期。Spring 提供多种作用域,默认是 singleton。通过 @Scope 注解指定,如 @Scope("prototype")。 - singleton(单例):容器中只有一个实例,所有请求共享该实例(默认值)。 - prototype(多例):每次请求(如 getBean())都会创建新实例,容器不管理其销毁。 - request(Web):每个 HTTP 请求创建一个实例,仅在当前请求有效。 - session(Web):每个会话创建一个实例,在会话有效期内有效。 ## 2.5 生命周期 1. 实例化(Instantiation) 容器通过构造器创建 Bean 实例(分配内存)。 2. 属性注入(Population) 容器将依赖的 Bean 注入到当前 Bean 的字段或方法(如 @Autowired 标注的依赖)。 3. 初始化前(Post-processing before initialization) 执行 BeanPostProcessor 的 postProcessBeforeInitialization 方法(AOP 代理生成在此阶段)。 4. 初始化(Initialization) 调用 @PostConstruct 注解的方法(JSR-250 标准,推荐)。 若实现 InitializingBean 接口,调用 afterPropertiesSet() 方法。 执行自定义初始化方法(如 @Bean(initMethod = "init") 中指定的 init 方法)。 5. 初始化后(Post-processing after initialization) 执行 BeanPostProcessor 的 postProcessAfterInitialization 方法。 6. 使用(In Use) Bean 被应用程序调用。 7. 销毁(Destruction) 调用 @PreDestroy 注解的方法(JSR-250 标准,推荐)。 若实现 DisposableBean 接口,调用 destroy() 方法。 执行自定义销毁方法(如 @Bean(destroyMethod = "destroy") 中指定的 destroy 方法)。 ![暂无图片](https://cxx0822.iepose.cn/rustfs/blog/b1054386c885ffefb0f08074ad6b6268.png 'Bean生命周期.png') # 三、BeanDefinition ## 3.1 定义   BeanDefinition是Spring框架中描述Bean的元数据对象,它包含了创建Bean实例所需的所有信息。 ## 3.2 作用 - 定义Bean的类名 - 设置Bean的作用域 - 配置Bean的属性值 - 定义依赖关系 - 配置初始化/销毁方法 ## 3.3 结构 ```xml BeanDefinition (接口) ↑ AbstractBeanDefinition (抽象类) ↑ RootBeanDefinition, GenericBeanDefinition, ChildBeanDefinition ``` ## 3.4 关键属性 ```java public interface BeanDefinition { // Bean的类名 void setBeanClassName(String beanClassName); String getBeanClassName(); // 作用域(singleton、prototype等) void setScope(String scope); String getScope(); // 是否延迟初始化 void setLazyInit(boolean lazyInit); boolean isLazyInit(); // 依赖的Bean名称 void setDependsOn(String... dependsOn); String[] getDependsOn(); // 初始化方法 void setInitMethodName(String initMethodName); String getInitMethodName(); // 销毁方法 void setDestroyMethodName(String destroyMethodName); String getDestroyMethodName(); // 工厂方法名 void setFactoryMethodName(String factoryMethodName); String getFactoryMethodName(); } ``` ## 3.5 创建过程 ```java // 编程方式创建BeanDefinition GenericBeanDefinition beanDefinition = new GenericBeanDefinition(); beanDefinition.setBeanClassName("com.example.UserService"); beanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON); beanDefinition.setLazyInit(false); // 注册到BeanFactory DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); beanFactory.registerBeanDefinition("userService", beanDefinition); ``` # 四、BeanFactory ## 4.1 定义   BeanFactory是Spring IOC容器的根接口,提供了最基本的IOC功能。它是访问Spring容器的基本客户端视图。 ## 4.2 结构 ```xml BeanFactory (根接口) ↑ ListableBeanFactory, HierarchicalBeanFactory, AutowireCapableBeanFactory ↑ ConfigurableBeanFactory, ConfigurableListableBeanFactory ↑ DefaultListableBeanFactory (主要实现类) ``` ## 4.3 核心方法 ```java public interface BeanFactory { // 根据名称获取Bean实例 Object getBean(String name) throws BeansException; // 根据名称和类型获取Bean实例 T getBean(String name, Class requiredType) throws BeansException; // 根据类型获取Bean实例 T getBean(Class requiredType) throws BeansException; // 判断是否包含指定名称的Bean boolean containsBean(String name); // 判断Bean是否是单例 boolean isSingleton(String name) throws NoSuchBeanDefinitionException; // 判断Bean是否是原型 boolean isPrototype(String name) throws NoSuchBeanDefinitionException; // 获取Bean的类型 Class getType(String name) throws NoSuchBeanDefinitionException; } ``` ## 4.4 使用示例 ```java // 创建BeanFactory实例 DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); // 创建BeanDefinition GenericBeanDefinition beanDefinition = new GenericBeanDefinition(); beanDefinition.setBeanClassName("com.example.UserService"); // 注册BeanDefinition beanFactory.registerBeanDefinition("userService", beanDefinition); // 获取Bean实例 UserService userService = beanFactory.getBean("userService", UserService.class); ``` ## 4.5 特点 - 轻量级:功能相对简单,资源消耗少 - 延迟加载:默认在第一次请求时才创建Bean实例 - 基础功能:提供最基本的IOC功能 # 五、ApplicationContext ★★★ ## 5.1 定义   ApplicationContext是BeanFactory的子接口,在BeanFactory的基础上提供了更多企业级功能,是Spring容器的完整实现。 ## 5.2 结构 ```xml BeanFactory ↑ ApplicationContext (扩展接口) ↑ ConfigurableApplicationContext ↑ AbstractApplicationContext ↑ ClassPathXmlApplicationContext, FileSystemXmlApplicationContext, AnnotationConfigApplicationContext, WebApplicationContext ``` ## 5.3 特点 - 完整的IOC功能:包含BeanFactory的所有功能 - 预实例化单例Bean:默认在启动时创建单例Bean - 企业级功能:支持AOP、事务管理、国际化等 - 资源访问:统一的资源访问接口 - 事件机制:支持应用内事件发布/订阅 ## 5.4 refresh方法 ```java // AbstractApplicationContext.java /** * Spring ApplicationContext 的核心启动方法 * 定义了容器初始化的完整生命周期 */ public void refresh() throws BeansException, IllegalStateException { // 使用同步锁确保容器启动的线程安全性,防止并发刷新 synchronized (this.startupShutdownMonitor) { // [1] 准备刷新容器 - 设置启动状态,验证环境配置 prepareRefresh(); // [2] 获取或创建BeanFactory - 创建DefaultListableBeanFactory实例 // 如果是XML配置,会在这里加载和解析XML文件 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // [3] 配置BeanFactory - 设置类加载器、注册核心BeanPostProcessor等 prepareBeanFactory(beanFactory); try { // [4] 后处理BeanFactory - 模板方法,允许子类进行特殊配置 // Web应用会在这里注册Servlet相关的Scope postProcessBeanFactory(beanFactory); // [5] 🚀 关键步骤:调用BeanFactory后置处理器 // 执行BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor // ConfigurationClassPostProcessor在这里扫描@Component、@Configuration等注解 invokeBeanFactoryPostProcessors(beanFactory); // [6] 注册Bean后置处理器 - 注册所有BeanPostProcessor // 包括AOP、事务、自定义的BeanPostProcessor,此时只是注册,还未执行 registerBeanPostProcessors(beanFactory); // [7] 初始化消息源 - 设置国际化消息资源 // 用于支持多语言消息解析 initMessageSource(); // [8] 初始化应用事件广播器 - 创建事件发布机制的核心组件 // 用于发布ApplicationEvent事件 initApplicationEventMulticaster(); // [9] 模板方法:子类可以在这里执行特殊的刷新逻辑 // SpringBoot在这里启动内嵌的Tomcat服务器 onRefresh(); // [10] 注册监听器 - 将所有ApplicationListener注册到事件广播器 // 包括静态指定的监听器和从BeanFactory中获取的监听器 registerListeners(); // [11] 🏭 核心步骤:完成BeanFactory的初始化 // 实例化所有非懒加载的单例Bean,执行依赖注入、AOP代理等 finishBeanFactoryInitialization(beanFactory); // [12] 完成刷新过程 - 发布ContextRefreshedEvent事件 // 标记容器启动完成,可以正常工作了 finishRefresh(); } catch (BeansException ex) { // 如果刷新过程中出现异常,需要销毁已经创建的单例Bean,防止资源泄漏 if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // 销毁已经创建的单例Bean destroyBeans(); // 重置容器状态为未激活 cancelRefresh(ex); // 重新抛出异常 throw ex; } finally { // 最后重置一些公共的缓存,比如反射缓存 resetCommonCaches(); } } } ``` ### 5.4.1 prepareRefresh() ```java protected void prepareRefresh() { this.startupDate = System.currentTimeMillis(); this.closed.set(false); this.active.set(true); if (logger.isInfoEnabled()) { logger.info("Refreshing " + this); } initPropertySources(); getEnvironment().validateRequiredProperties(); this.earlyApplicationEvents = new LinkedHashSet<>(); } ``` - 这是容器启动的第一步,主要做初始化准备工作 - 设置容器的启动时间戳和活跃状态 - 验证必要的环境属性是否配置正确(比如通过@Value注解标记为必须的属性) - 初始化早期事件集合,用于存储在事件多播器创建前发布的事件 - 为整个刷新过程奠定基础状态 ### 5.4.2 obtainFreshBeanFactory() ```java protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { refreshBeanFactory(); return getBeanFactory(); } // 子类实现示例 protected final void refreshBeanFactory() throws IllegalStateException { if (hasBeanFactory()) { destroyBeans(); closeBeanFactory(); } try { DefaultListableBeanFactory beanFactory = createBeanFactory(); customizeBeanFactory(beanFactory); loadBeanDefinitions(beanFactory); this.beanFactory = beanFactory; } catch (IOException ex) { throw new ApplicationContextException("I/O error", ex); } } ``` - 创建或刷新底层的BeanFactory(Spring容器的核心工厂) - 如果是刷新操作,会先销毁旧的BeanFactory和所有Bean实例 - 创建新的DefaultListableBeanFactory实例 - 加载Bean定义(从XML文件或注解配置中解析Bean的元数据) - 这个步骤完成后,容器就知道了有哪些Bean需要管理,但还没有创建Bean实例 ### 5.4.3 prepareBeanFactory() ```java protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { beanFactory.setBeanClassLoader(getClassLoader()); beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver()); beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); beanFactory.ignoreDependencyInterface(EnvironmentAware.class); beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ApplicationContext.class, this); } ``` - 配置BeanFactory的基本设置和功能组件 - 设置类加载器、SPEL表达式解析器、属性编辑器 - 注册ApplicationContextAwareProcessor,这是实现各种Aware接口的关键 - 忽略某些接口的依赖注入(这些接口由容器特殊处理) - 注册可解析的依赖关系,当Bean需要这些类型时直接返回容器实例 - 为BeanFactory添加基本的功能支持 ### 5.4.4 postProcessBeanFactory() ```java protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { // 空方法 - 模板方法模式 // 子类可以覆盖此方法添加特定逻辑 } ``` - 模板方法,允许子类在标准初始化后对BeanFactory进行自定义配置 - 在Web环境中,会在这里注册Servlet相关的Scope(request、session等) - 可以添加特定环境的BeanPostProcessor或进行其他特殊配置 - 这是框架扩展的重要切入点 ### 5.4.5 invokeBeanFactoryPostProcessors() ```java protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); } ``` - 🚀 这是最关键的一步,负责扫描和注册所有的Bean定义 - 执行所有BeanFactoryPostProcessor,它们可以修改Bean的定义信息 - 特别是ConfigurationClassPostProcessor,它负责: 扫描@Component、@Service、@Repository等注解 处理@Configuration配置类 解析@Bean方法定义 处理@Import、@ComponentScan等注解 - 这一步完成后,所有的Bean定义都已经被解析和注册 ### 5.4.6 registerBeanPostProcessors() ```java protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this); } ``` - 注册所有的BeanPostProcessor到BeanFactory中 - 包括AOP、事务管理、自定义的Bean后置处理器等 - 注意:此时只是注册,真正的调用要等到Bean实例化时 - 这些处理器按照优先级顺序注册,确保执行顺序正确 - 这是Spring AOP和事务管理等高级功能的基础 ### 5.4.7 initMessageSource() ```java protected void initMessageSource() { ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) { this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class); } else { DelegatingMessageSource dms = new DelegatingMessageSource(); this.messageSource = dms; beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource); } } ``` - 初始化国际化消息支持 - 如果用户配置了自定义的MessageSource,就使用用户的配置 - 否则创建默认的DelegatingMessageSource - 支持从属性文件读取多语言消息,实现国际化功能 - 用于解析${}占位符和国际化消息 ### 5.4.8 initApplicationEventMulticaster() ```java protected void initApplicationEventMulticaster() { ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) { this.applicationEventMulticaster = beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class); } else { this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory); beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster); } } ``` - 初始化应用事件发布机制的核心组件 - 如果用户配置了自定义的事件广播器,就使用用户的配置 - 否则创建默认的SimpleApplicationEventMulticaster - 这个组件负责将应用事件广播给所有监听器 - 支持观察者模式,实现应用内组件间的解耦通信 ### 5.4.9 onRefresh() - 刷新时扩展点 ```java protected void onRefresh() throws BeansException { // 空方法 - 模板方法 } ``` - 模板方法,允许子类在特定时机执行自定义逻辑 - 在Spring Boot中,这里会启动内嵌的Web服务器(Tomcat、Jetty等) - 在Spring MVC中,这里会初始化HandlerMapping、HandlerAdapter等组件 - 这是框架扩展的重要切入点,不同的ApplicationContext实现有不同的行为 ### 5.4.10 registerListeners() ```java protected void registerListeners() { for (ApplicationListener listener : getApplicationListeners()) { getApplicationEventMulticaster().addApplicationListener(listener); } String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false); for (String listenerBeanName : listenerBeanNames) { getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName); } // 发布早期事件 if (this.earlyApplicationEvents != null) { for (ApplicationEvent earlyEvent : this.earlyApplicationEvents) { getApplicationEventMulticaster().multicastEvent(earlyEvent); } } } ``` - 注册所有的事件监听器到事件广播器 - 包括静态注册的监听器和从BeanFactory中获取的监听器Bean - 发布在监听器注册前收集的早期事件 - 确保事件发布机制完整可用,应用事件能够正确分发 ### 5.4.11 finishBeanFactoryInitialization() ```java protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME)) { beanFactory.setConversionService(beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)); } if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); } beanFactory.freezeConfiguration(); beanFactory.preInstantiateSingletons(); } ``` - 🏭 这是最核心的步骤,真正创建Bean实例 - 初始化类型转换服务(ConversionService) - 注册嵌入式值解析器(用于解析${}占位符) - 冻结Bean定义,防止后续修改 - 实例化所有非懒加载的单例Bean,这个过程中会: 创建Bean实例 执行依赖注入(@Autowired、@Resource等) 执行BeanPostProcessor(AOP代理在这里发生) 调用初始化方法(@PostConstruct、InitializingBean) - 这是容器启动过程中最耗时的步骤 ### 5.4.12 finishRefresh() ```java protected void finishRefresh() { clearResourceCaches(); initLifecycleProcessor(); getLifecycleProcessor().onRefresh(); publishEvent(new ContextRefreshedEvent(this)); LiveBeansView.registerApplicationContext(this); } ``` - 完成容器的启动过程,进行最后的清理和通知工作 - 清除资源缓存,释放临时资源 - 初始化生命周期处理器,管理Bean的生命周期 - 发布ContextRefreshedEvent事件,通知所有监听器容器已启动完成 - 注册LiveBeansView(用于监控和调试) - 标记整个容器启动流程结束,容器进入就绪状态 ### 5.4.13 总结   refresh()方法按固定顺序执行12个步骤,核心可归纳为:**准备容器环境 → 解析并注册Bean定义→ 初始化事件、消息等基础设施 → 实例化所有非懒加载的单例Bean→ 完成启动并发布事件**。整个过程通过模板方法模式定义,确保了扩展性和一致性。   核心在于两个关键扩展机制:**BeanFactoryPostProcessor在Bean定义阶段介入,负责修改和注册Bean的定义信息;BeanPostProcessor在Bean实例化阶段介入,负责对创建好的Bean实例进行增强和包装。**