框架
spring
控制反转(IoC)和依赖注入(DI)
Spring AOP(面向切面编程)
Spring 事务
本文档使用 MrDoc 发布
-
+
首页
控制反转(IoC)和依赖注入(DI)
## 控制反转(Inversion of Control, IoC) * 传统开发模式:对象的创建、依赖管理和生命周期由开发者手动控制(例如通过 new 关键字实例化对象)。 * IoC 模式:将对象的创建和依赖关系的控制权交给 IoC 容器(由框架管理),开发者只需声明需要什么对象,而不是手动创建它们。 * 核心思想:“好莱坞原则”(Don’t call us, we’ll call you)——框架负责调用你的代码,而不是你调用框架。 ### IoC 解决的问题 * 耦合度高:传统代码中,类直接依赖具体实现(如 new UserServiceImpl()),难以替换或修改依赖。 * 代码冗余:重复的创建和组装对象代码。 * 可测试性差:难以通过模拟依赖进行单元测试。 ## 依赖注入(Dependency Injection, DI) * DI 是 IoC 的具体实现方式:通过容器将对象所依赖的其他对象自动注入(传递)给它,而不是由对象自己创建依赖。 * 核心目标:解耦,让类只关注自身逻辑,而不关心如何获取依赖。 ### 依赖注入 * 构造函数注入 * Setter 方法注入 * 字段注入(通过注解) ## Spring IoC 容器 容器的核心角色 * Bean:由 Spring 容器管理的对象称为 Bean。 * IoC 容器:负责创建 Bean、管理 Bean 的依赖关系及生命周期。 * 核心接口: * BeanFactory:基础容器,提供基本的依赖注入功能。 * ApplicationContext:扩展自 BeanFactory,提供企业级功能(如国际化、事件发布等)。 ### 配置方式 * XML 配置(传统方式) 在 XML 文件中定义 Bean 及其依赖: ``` <bean id="userRepository" class="com.example.UserRepositoryImpl"/> <bean id="userService" class="com.example.UserService"> <constructor-arg ref="userRepository"/> </bean> ``` * Java 注解配置(现代主流) 使用 @Component、@Service 等注解标记 Bean,@Autowired 注入依赖: ``` @Service public class UserService { private final UserRepository userRepository; @Autowired public UserService(UserRepository userRepository) { this.userRepository = userRepository; } } ``` * Java Config 配置 通过 @Configuration 和 @Bean 注解显式定义 Bean: ``` @Configuration public class AppConfig { @Bean public UserRepository userRepository() { return new UserRepositoryImpl(); } @Bean public UserService userService() { return new UserService(userRepository()); } } ``` ## 依赖注入的优势 * 降低耦合度:类不直接依赖具体实现,而是依赖接口。 * 提高可维护性:修改依赖时只需调整配置,无需改动业务代码。 * 便于测试:可通过 Mock 对象注入依赖,轻松实现单元测试。 * 代码更简洁:避免手动管理对象创建和依赖组装。 ## springbean的生命周期  1. **Bean 的实例化** * 触发时机:容器启动时(单例 Bean 默认预加载)或首次请求时(如原型 Bean 或延迟加载 Bean)。 * 实现方式: * 通过反射调用无参构造函数。 * 若定义了工厂方法(如 @Bean 方法或 XML 的 factory-method),则调用工厂方法创建实例。 2. **设置属性值(依赖注入)** * 方式: * 通过构造函数注入(推荐)。 * 通过 Setter 方法或字段注入(如 @Autowired)。 * 容器行为:根据 Bean 定义解析依赖关系,递归完成所有依赖的注入。 3. **Aware 接口回调** Spring 提供了一系列 Aware 接口,用于让 Bean 感知容器环境: * BeanNameAware * 调用 setBeanName(String name),传入 Bean 的 ID/名称。 * 用途:获取 Bean 在容器中的标识。 * BeanFactoryAware * 调用 setBeanFactory(BeanFactory beanFactory),传入 BeanFactory 实例。 * 用途:直接操作容器或获取其他 Bean。 * ApplicationContextAware * 调用 setApplicationContext(ApplicationContext context),传入应用上下文。 * 用途:访问资源、国际化、事件发布等高级功能。 4. **BeanPostProcessor 的前置处理** * 方法:postProcessBeforeInitialization(Object bean, String beanName) * 作用:在 Bean 初始化(如 @PostConstruct)之前,对 Bean 实例进行修改或增强。 * 典型应用:生成代理对象(如 AOP)、属性校验等。 5. **初始化阶段** * InitializingBean 接口 * 调用 afterPropertiesSet(),确保所有依赖注入完成后执行自定义逻辑。 * 自定义初始化方法 * 通过 @PostConstruct 注解、XML 的 init-method 或 @Bean(initMethod = "xxx") 定义。 * 执行顺序:@PostConstruct → afterPropertiesSet() → init-method。 6. **BeanPostProcessor 的后置处理** * 方法:postProcessAfterInitialization(Object bean, String beanName) * 作用:在 Bean 初始化之后进一步处理,例如生成最终的代理对象。 * 典型应用:AOP 动态代理的最终生成在此阶段完成。 7. **Bean 的使用** * 单例(Singleton):Bean 实例被缓存,后续请求直接返回同一对象。 * 原型(Prototype):每次请求返回新实例,容器不管理其销毁。 ## Bean 的销毁阶段 当容器关闭(如调用 close())时,销毁单例 Bean: 1. @PreDestroy 注解方法:标记销毁前的清理逻辑。 2. DisposableBean 接口:调用 destroy() 方法。 3. 自定义销毁方法:通过 XML 的 destroy-method 或 @Bean(destroyMethod = "xxx") 定义。 执行顺序:@PreDestroy → destroy() → destroy-method。 ## 三级缓存 Spring 容器内部维护三个核心缓存(Map 结构): | 缓存名称 | 存储内容 | 作用 | |-----------------------|--------------------------------|-----------------------------------| | singletonObjects | 完全初始化好的单例 Bean(一级缓存) | 存放可直接使用的最终 Bean | | earlySingletonObjects | 提前暴露的“早期引用”(二级缓存) | 解决循环依赖时临时存放半成品 Bean | | singletonFactories | Bean 的工厂对象(ObjectFactory,三级缓存) | 生成原始 Bean 或代理对象的工厂,确保 AOP 等扩展的正确性 |
admin
2025年3月10日 09:28
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Rancher
Jenkins
ADMIN-UI
VBEN-ADMIN-UI
RUST-FS
MinIO
mindoc
Markdown文件
PDF文档(打印)
分享
链接
类型
密码
更新密码