跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
Spring依赖注入
”︁(章节)
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
= Spring依赖注入 = == 介绍 == '''依赖注入'''(Dependency Injection,简称DI)是Spring框架的核心特性之一,它允许对象通过外部容器(如Spring IoC容器)来获取其依赖的其他对象,而不是由对象自身创建或查找依赖项。这种方式降低了代码的耦合度,提高了可测试性和可维护性。 在Spring中,依赖注入主要有三种方式: * '''构造器注入'''(Constructor Injection) * '''Setter注入'''(Setter Injection) * '''字段注入'''(Field Injection) == 依赖注入的类型 == === 构造器注入 === 构造器注入是通过类的构造函数来注入依赖项。这是Spring官方推荐的方式,因为它可以确保依赖项在对象创建时就被注入,并且依赖项不可变(final)。 <syntaxhighlight lang="java"> public class UserService { private final UserRepository userRepository; // 构造器注入 public UserService(UserRepository userRepository) { this.userRepository = userRepository; } public void saveUser(User user) { userRepository.save(user); } } </syntaxhighlight> 在Spring配置中,可以通过XML或注解方式配置构造器注入: <syntaxhighlight lang="xml"> <bean id="userRepository" class="com.example.UserRepositoryImpl" /> <bean id="userService" class="com.example.UserService"> <constructor-arg ref="userRepository" /> </bean> </syntaxhighlight> === Setter注入 === Setter注入是通过类的setter方法来注入依赖项。这种方式允许依赖项在对象创建后动态变更。 <syntaxhighlight lang="java"> public class OrderService { private PaymentService paymentService; // Setter注入 public void setPaymentService(PaymentService paymentService) { this.paymentService = paymentService; } public void processOrder(Order order) { paymentService.processPayment(order); } } </syntaxhighlight> XML配置示例: <syntaxhighlight lang="xml"> <bean id="paymentService" class="com.example.PaymentServiceImpl" /> <bean id="orderService" class="com.example.OrderService"> <property name="paymentService" ref="paymentService" /> </bean> </syntaxhighlight> === 字段注入 === 字段注入是直接在字段上使用注解(如`@Autowired`)来注入依赖项。这种方式虽然简洁,但不利于测试和代码的可维护性。 <syntaxhighlight lang="java"> public class ProductService { @Autowired private InventoryService inventoryService; public void checkStock(Product product) { inventoryService.checkStock(product); } } </syntaxhighlight> == 依赖注入的实际应用 == === 场景:电商系统中的订单处理 === 假设有一个电商系统,订单处理服务(`OrderService`)依赖于支付服务(`PaymentService`)和库存服务(`InventoryService`)。通过依赖注入,可以灵活地替换具体的实现类。 <syntaxhighlight lang="java"> public class OrderService { private final PaymentService paymentService; private final InventoryService inventoryService; // 构造器注入 public OrderService(PaymentService paymentService, InventoryService inventoryService) { this.paymentService = paymentService; this.inventoryService = inventoryService; } public void placeOrder(Order order) { inventoryService.reserveStock(order); paymentService.charge(order); } } </syntaxhighlight> === 使用注解配置依赖注入 === Spring支持使用`@Autowired`或`@Resource`注解来自动装配依赖项。 <syntaxhighlight lang="java"> @Service public class OrderService { private final PaymentService paymentService; private final InventoryService inventoryService; @Autowired public OrderService(PaymentService paymentService, InventoryService inventoryService) { this.paymentService = paymentService; this.inventoryService = inventoryService; } } </syntaxhighlight> == 依赖注入的优势 == * '''解耦''':对象不需要知道如何创建或查找依赖项。 * '''可测试性''':可以轻松替换依赖项的实现(如使用Mock对象)。 * '''可维护性''':依赖关系清晰,便于重构和扩展。 == 依赖注入的底层原理 == Spring IoC容器通过以下步骤实现依赖注入: 1. 扫描并注册Bean定义。 2. 解析Bean之间的依赖关系。 3. 创建Bean实例并注入依赖项。 <mermaid> graph TD A[启动Spring容器] --> B[扫描Bean定义] B --> C[解析依赖关系] C --> D[创建Bean实例] D --> E[注入依赖项] </mermaid> == 常见问题与解决方案 == === 循环依赖问题 === 当两个Bean互相依赖时,可能会导致循环依赖问题。例如: <syntaxhighlight lang="java"> @Service public class ServiceA { @Autowired private ServiceB serviceB; } @Service public class ServiceB { @Autowired private ServiceA serviceA; } </syntaxhighlight> '''解决方案''': * 使用构造器注入时,Spring会抛出`BeanCurrentlyInCreationException`。 * 使用Setter或字段注入时,Spring可以通过三级缓存解决循环依赖。 === 依赖冲突 === 当有多个相同类型的Bean时,Spring会抛出`NoUniqueBeanDefinitionException`。 '''解决方案''': * 使用`@Qualifier`注解指定Bean名称。 * 使用`@Primary`注解标记首选Bean。 == 总结 == 依赖注入是Spring框架的核心机制,它通过外部容器管理对象及其依赖关系,提高了代码的灵活性和可维护性。开发者应根据具体场景选择合适的注入方式(推荐优先使用构造器注入),并注意避免循环依赖和依赖冲突问题。 [[Category:后端框架]] [[Category:Spring]] [[Category:Spring Ioc容器]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)