Files
blog-press/docs/SpringBoot/SpringIOC.md
2025-11-26 23:48:43 +08:00

544 lines
21 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 一、IOC
  Spring框架的核心是IOC控制反转容器它负责管理应用程序中的对象称为Bean的创建、配置和组装。
# 二、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配置
<bean id="userService" class="com.example.UserService"/>
```
## 2.4 作用域
&emsp;&emsp;控制 Bean 在容器中的实例数量和生命周期。Spring 提供多种作用域,默认是 singleton。通过 @Scope 注解指定,如 @Scope("prototype")。
- singleton单例容器中只有一个实例所有请求共享该实例默认值
- prototype多例每次请求如 getBean())都会创建新实例,容器不管理其销毁。
- requestWeb每个 HTTP 请求创建一个实例,仅在当前请求有效。
- sessionWeb每个会话创建一个实例在会话有效期内有效。
## 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 UseBean 被应用程序调用。
7. 销毁Destruction
调用 @PreDestroy 注解的方法JSR-250 标准,推荐)。
若实现 DisposableBean 接口,调用 destroy() 方法。
执行自定义销毁方法(如 @Bean(destroyMethod = "destroy") 中指定的 destroy 方法)。
![暂无图片](https://cxx0822.iepose.cn/rustfs/blog/b1054386c885ffefb0f08074ad6b6268.png 'Bean生命周期.png')
# 三、BeanDefinition
## 3.1 定义
&emsp;&emsp;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 定义
&emsp;&emsp;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> T getBean(String name, Class<T> requiredType) throws BeansException;
// 根据类型获取Bean实例
<T> T getBean(Class<T> 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 定义
&emsp;&emsp;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);
}
}
```
- 创建或刷新底层的BeanFactorySpring容器的核心工厂
- 如果是刷新操作会先销毁旧的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相关的Scoperequest、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等
执行BeanPostProcessorAOP代理在这里发生
调用初始化方法(@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 总结
&emsp;&emsp;refresh()方法按固定顺序执行12个步骤核心可归纳为准备容器环境 → 解析并注册Bean定义→ 初始化事件、消息等基础设施 → 实例化所有非懒加载的单例Bean→ 完成启动并发布事件。整个过程通过模板方法模式定义,确保了扩展性和一致性。
&emsp;&emsp;核心在于两个关键扩展机制BeanFactoryPostProcessor在Bean定义阶段介入负责修改和注册Bean的定义信息BeanPostProcessor在Bean实例化阶段介入负责对创建好的Bean实例进行增强和包装。