当前位置: 首页 > ds >正文

【Spring】Spring中8种常见依赖注入使用示例

在 Spring 中,IoC 注入可以通过多种方式实现,涵盖不同场景的依赖管理。以下是 8 种常见场景的详细示例及说明,结合 XML、注解和 Java 配置类三种方式。


1. 构造器注入(推荐方式)

通过构造器传递依赖,确保对象不可变且依赖完整。

注解方式:
@Service
public class OrderService {private final PaymentService paymentService;@Autowired // Spring 4.3+ 可省略(单构造器时)public OrderService(PaymentService paymentService) {this.paymentService = paymentService;}
}@Component
public class PaymentService {public void process() {System.out.println("Processing payment...");}
}
XML 方式:
<bean id="paymentService" class="com.example.PaymentService"/><bean id="orderService" class="com.example.OrderService"><constructor-arg ref="paymentService"/>
</bean>
Java 配置类:
@Configuration
public class AppConfig {@Beanpublic PaymentService paymentService() {return new PaymentService();}@Beanpublic OrderService orderService() {return new OrderService(paymentService());}
}

2. Setter 注入

通过 Setter 方法注入依赖,适合可选依赖或需要动态变更的场景。

注解方式:
@Service
public class ProductService {private InventoryService inventoryService;@Autowiredpublic void setInventoryService(InventoryService inventoryService) {this.inventoryService = inventoryService;}
}@Component
public class InventoryService {public void checkStock() {System.out.println("Checking stock...");}
}
XML 方式:
<bean id="inventoryService" class="com.example.InventoryService"/><bean id="productService" class="com.example.ProductService"><property name="inventoryService" ref="inventoryService"/>
</bean>

3. 字段注入(不推荐,但常见)

直接通过字段注入依赖,简洁但隐藏依赖关系。

@Service
public class CartService {@Autowiredprivate DiscountService discountService;
}@Component
public class DiscountService {public void applyDiscount() {System.out.println("Applying discount...");}
}

4. 集合注入(多个同类型 Bean)

注入多个相同接口/父类的实现类。

示例代码:
public interface NotificationSender {void send(String message);
}@Component
public class EmailSender implements NotificationSender {@Overridepublic void send(String message) {System.out.println("Email: " + message);}
}@Component
public class SmsSender implements NotificationSender {@Overridepublic void send(String message) {System.out.println("SMS: " + message);}
}
注入方式:
@Service
public class NotificationService {private final List<NotificationSender> senders;@Autowiredpublic NotificationService(List<NotificationSender> senders) {this.senders = senders;}public void broadcast(String message) {senders.forEach(sender -> sender.send(message));}
}

5. 条件注入(@Qualifier 或 @Primary)

解决多个同类型 Bean 的歧义性问题。

使用 @Qualifier
public interface DataSource {void connect();
}@Component("mysqlDataSource")
public class MySqlDataSource implements DataSource {@Overridepublic void connect() {System.out.println("MySQL connected");}
}@Component("oracleDataSource")
public class OracleDataSource implements DataSource {@Overridepublic void connect() {System.out.println("Oracle connected");}
}@Service
public class ReportService {private final DataSource dataSource;@Autowiredpublic ReportService(@Qualifier("mysqlDataSource") DataSource dataSource) {this.dataSource = dataSource;}
}
使用 @Primary
@Configuration
public class AppConfig {@Bean@Primary // 默认优先选择public DataSource mysqlDataSource() {return new MySqlDataSource();}@Beanpublic DataSource oracleDataSource() {return new OracleDataSource();}
}

6. 外部化配置注入(@Value)

注入配置文件(如 application.properties)中的值。

配置文件:
app.name=MySpringApp
app.max.connections=10
注入方式:
@Component
public class AppConfigBean {@Value("${app.name}")private String appName;@Value("${app.max.connections}")private int maxConnections;// Getter/Setter
}

7. 循环依赖处理

构造器注入无法解决循环依赖,需改用 Setter 注入。

示例代码:
@Service
public class ServiceA {private ServiceB serviceB;@Autowiredpublic void setServiceB(ServiceB serviceB) {this.serviceB = serviceB;}
}@Service
public class ServiceB {private ServiceA serviceA;@Autowiredpublic void setServiceA(ServiceA serviceA) {this.serviceA = serviceA;}
}

8. 条件化 Bean 注入(@Profile 或 @Conditional)

根据环境或条件动态选择 Bean。

使用 @Profile
@Configuration
public class DataSourceConfig {@Bean@Profile("dev")public DataSource devDataSource() {return new H2DataSource();}@Bean@Profile("prod")public DataSource prodDataSource() {return new MySqlDataSource();}
}
使用 @Conditional
public class MongoDBCondition implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {return "true".equals(context.getEnvironment().getProperty("enable.mongo"));}
}@Configuration
public class DatabaseConfig {@Bean@Conditional(MongoDBCondition.class)public DataSource mongoDataSource() {return new MongoDataSource();}
}

总结

  • 构造器注入:推荐用于强制依赖,确保对象不可变。
  • Setter/字段注入:适合可选依赖或需要灵活性的场景。
  • 集合注入:处理多实现类的统一管理。
  • 条件注入:通过 @Qualifier@Primary@Profile 解决歧义。
  • 循环依赖:优先通过设计避免,或改用 Setter 注入。
  • 外部化配置:结合 @Value 动态注入属性值。
  • 条件化 Bean:根据环境或业务规则动态装配。

具体选择取决于项目需求,Spring Boot 进一步简化了配置(如自动配置、@ConditionalOnProperty)。

http://www.xdnf.cn/news/3841.html

相关文章:

  • 健康养生新主张
  • web应用开发说明文档
  • matlab学习之旅
  • 数据结构---
  • 实战项目:基于控制台与数据库的图书管理系统开发指南
  • C语言中memmove和memcpy
  • 智慧校园整体解决方案-5PPT(65页)
  • python中的异常处理
  • 【CF】Day50——Codeforces Round 960 (Div. 2) BCD
  • 数学实验Matlab
  • 多把锁以及线程死锁问题
  • Linux-GRUB全面指南
  • CUDA输出“hello world”
  • 多数据源动态切换
  • 算法每日一题 | 入门-顺序结构-数字反转
  • (38)VTK C++开发示例 ---纹理裁剪
  • C++负载均衡远程调用学习之异步消息任务功能与连接属性
  • CVPR2021 | 重新思考视觉Transformer中的自注意力机制
  • Java学习手册:Spring 生态其他组件介绍
  • 单细胞测序试验设计赏析(一)
  • AWS在跨境电商中的全场景实践与未来生态构建
  • D. 例题3.2.2 整数划分问题
  • 二种MVCC对比分析
  • 学习黑客风险Risk
  • iOS启动优化:从原理到实践
  • 2025年渗透测试面试题总结-拷打题库35(题目+回答)
  • 【C++】:C++17新特性
  • Vivado FPGA 开发 | 创建工程 / 仿真 / 烧录
  • 2845. 统计趣味子数组的数目
  • 【LLaMA-Factory实战】Web UI快速上手:可视化大模型微调全流程