spring-boot-dependency-injection
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSpring Boot Dependency Injection
Spring Boot 依赖注入
This skill captures the dependency injection approach promoted in this repository: constructor-first design, explicit optional collaborators, and deterministic configuration that keeps services testable and framework-agnostic.
本技能收录了本仓库所推崇的依赖注入方法:构造器优先设计、显式可选协作者,以及确保服务可测试且与框架无关的确定性配置。
Overview
概述
- Prioritize constructor injection to keep dependencies explicit, immutable, and mockable.
- Treat optional collaborators through guarded setters or providers while documenting defaults.
- Resolve bean ambiguity intentionally through qualifiers, primary beans, and profiles.
- Validate wiring with focused unit tests before relying on Spring's TestContext framework.
- 优先使用构造器注入,使依赖关系明确、不可变且可模拟。
- 通过受保护的setter方法或提供者处理可选协作者,同时记录默认实现。
- 通过限定符、主Bean和配置文件有意解决Bean歧义问题。
- 在依赖Spring的TestContext框架之前,先通过聚焦的单元测试验证依赖注入。
When to Use
适用场景
- Implement constructor injection for new ,
@Service, or@Componentclasses.@Repository - Replace legacy field injection while modernizing Spring modules.
- Configure optional or pluggable collaborators (feature flags, multi-tenant adapters).
- Audit bean definitions before adding integration tests or migrating Spring Boot versions.
- 为新的、
@Service或@Component类实现构造器注入。@Repository - 在现代化Spring模块时替换传统的字段注入。
- 配置可选或可插拔的协作者(如功能标志、多租户适配器)。
- 在添加集成测试或迁移Spring Boot版本之前审核Bean定义。
Instructions
操作步骤
Follow these steps to implement proper dependency injection in Spring Boot:
按照以下步骤在Spring Boot中实现规范的依赖注入:
1. Identify Dependencies
1. 识别依赖
List all collaborators required by each class. Distinguish between mandatory dependencies (required for operation) and optional dependencies (feature-specific).
列出每个类所需的所有协作者。区分强制依赖(运行必需)和可选依赖(特定功能所需)。
2. Apply Constructor Injection
2. 应用构造器注入
Create constructors that accept all mandatory dependencies. Mark fields as final. Use Lombok @RequiredArgsConstructor to reduce boilerplate.
创建接收所有强制依赖的构造器。将字段标记为final。使用Lombok的@RequiredArgsConstructor减少样板代码。
3. Handle Optional Collaborators
3. 处理可选协作者
For optional dependencies, provide setter methods with @Autowired(required = false) or use ObjectProvider<T> for lazy resolution. Include default no-op implementations.
对于可选依赖,提供带有@Autowired(required = false)的setter方法,或使用ObjectProvider<T>实现延迟解析。包含默认的空操作实现。
4. Configure Beans
4. 配置Bean
Declare @Bean methods in @Configuration classes. Use conditional annotations (@ConditionalOnProperty, @ConditionalOnMissingBean) for environment-specific beans.
在@Configuration类中声明@Bean方法。使用条件注解(@ConditionalOnProperty、@ConditionalOnMissingBean)配置环境特定的Bean。
5. Resolve Ambiguity
5. 解决歧义
Apply @Primary to default implementations. Use @Qualifier with specific names when multiple beans of the same type exist.
为默认实现添加@Primary注解。当存在同一类型的多个Bean时,使用@Qualifier并指定具体名称。
6. Validate Wiring
6. 验证注入
Write unit tests that instantiate classes directly with mock dependencies. Add slice tests (@WebMvcTest, @DataJpaTest) to verify Spring context loads without errors.
编写直接实例化类并传入模拟依赖的单元测试。添加切片测试(@WebMvcTest、@DataJpaTest)以验证Spring上下文加载无错误。
7. Review Configuration
7. 审核配置
Ensure no field injection (@Autowired on fields) remains. Verify circular dependencies are resolved through domain events or extracted services.
确保不存在字段注入(字段上使用@Autowired)。通过领域事件或提取服务解决循环依赖问题。
Prerequisites
前置条件
- Align project with Java 17+ and Spring Boot 3.5.x (or later) to leverage records and .
@ServiceConnection - Keep build tooling ready to run or
./gradlew testfor validation.mvn test - Load supporting material from when deeper patterns or samples are required.
./references/
- 项目需适配Java 17+和Spring Boot 3.5.x(或更高版本),以使用records和。
@ServiceConnection - 准备好构建工具以运行或
./gradlew test进行验证。mvn test - 如需更深入的模式或示例,可从加载相关资料。
./references/
Workflow
工作流程
1. Map Collaborators
1. 映射协作者
- Inventory constructors, members, and configuration classes.
@Autowired - Classify dependencies as mandatory (must exist) or optional (feature-flagged, environment-specific).
- 盘点构造器、成员以及配置类。
@Autowired - 将依赖分类为强制依赖(必须存在)或可选依赖(功能标志控制、环境特定)。
2. Apply Constructor Injection
2. 应用构造器注入
- Introduce constructors (or Lombok ) that accept every mandatory collaborator.
@RequiredArgsConstructor - Mark injected fields and protect invariants with
finalif Lombok is not used.Objects.requireNonNull - Update or
@Configurationfactories to pass dependencies explicitly; consult@Beanfor canonical bean wiring../references/reference.md
- 添加接收所有强制协作者的构造器(或使用Lombok的)。
@RequiredArgsConstructor - 将注入字段标记为,如果不使用Lombok,使用
final保护不变量。Objects.requireNonNull - 更新或
@Configuration工厂以显式传递依赖;可参考@Bean中的标准Bean注入方式。./references/reference.md
3. Handle Optional Collaborators
3. 处理可选协作者
- Supply setters annotated with or inject
@Autowired(required = false)for lazy access.ObjectProvider<T> - Provide deterministic defaults (for example, no-op implementations) and document them inside configuration modules.
- Follow for a full workflow.
./references/examples.md#example-2-setter-injection-for-optional-dependencies
- 提供带有注解的setter方法,或注入
@Autowired(required = false)实现延迟访问。ObjectProvider<T> - 提供确定性的默认实现(例如空操作实现),并在配置模块中记录。
- 可参考获取完整流程。
./references/examples.md#example-2-setter-injection-for-optional-dependencies
4. Resolve Bean Selection
4. 解决Bean选择问题
- Choose for dominant implementations and
@Primaryfor niche variants.@Qualifier - Use profiles, conditional annotations, or factory methods to isolate environment-specific wiring.
- Reference for conditional and profile-based samples.
./references/reference.md#conditional-bean-registration
- 为主要实现选择,为特殊变体使用
@Primary。@Qualifier - 使用配置文件、条件注解或工厂方法隔离环境特定的注入。
- 可参考获取条件和基于配置文件的示例。
./references/reference.md#conditional-bean-registration
5. Validate Wiring
5. 验证注入
- Write unit tests that instantiate classes manually with mocks to prove Spring-free testability.
- Add slice or integration tests (,
@WebMvcTest,@DataJpaTest) only after constructor contracts are validated.@SpringBootTest - Reuse patterns in to select the proper test style.
./references/reference.md#testing-with-dependency-injection
- 编写手动实例化类并传入模拟对象的单元测试,证明无需Spring上下文即可测试。
- 仅在构造器契约验证通过后,添加切片或集成测试(、
@WebMvcTest、@DataJpaTest)。@SpringBootTest - 可复用中的模式选择合适的测试风格。
./references/reference.md#testing-with-dependency-injection
Examples
示例
Basic Constructor Injection
基础构造器注入
java
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
private final EmailService emailService;
public User register(UserRegistrationRequest request) {
User user = User.create(request.email(), request.name());
userRepository.save(user);
emailService.sendWelcome(user);
return user;
}
}- Instantiate directly in tests: with no Spring context required.
new UserService(mockRepo, mockEmailService);
java
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
private final EmailService emailService;
public User register(UserRegistrationRequest request) {
User user = User.create(request.email(), request.name());
userRepository.save(user);
emailService.sendWelcome(user);
return user;
}
}- 测试中可直接实例化:,无需Spring上下文。
new UserService(mockRepo, mockEmailService);
Intermediate: Optional Dependency with Guarded Setter
中级:带保护Setter的可选依赖
java
@Service
public class ReportService {
private final ReportRepository reportRepository;
private CacheService cacheService = CacheService.noOp();
public ReportService(ReportRepository reportRepository) {
this.reportRepository = reportRepository;
}
@Autowired(required = false)
public void setCacheService(CacheService cacheService) {
this.cacheService = cacheService;
}
}- Provide fallbacks such as to ensure deterministic behavior when the optional bean is absent.
CacheService.noOp()
java
@Service
public class ReportService {
private final ReportRepository reportRepository;
private CacheService cacheService = CacheService.noOp();
public ReportService(ReportRepository reportRepository) {
this.reportRepository = reportRepository;
}
@Autowired(required = false)
public void setCacheService(CacheService cacheService) {
this.cacheService = cacheService;
}
}- 提供等回退实现,确保可选Bean不存在时行为确定。
CacheService.noOp()
Advanced: Conditional Configuration Across Modules
高级:跨模块条件配置
java
@Configuration
@Import(DatabaseConfig.class)
public class MessagingConfig {
@Bean
@ConditionalOnProperty(name = "feature.notifications.enabled", havingValue = "true")
public NotificationService emailNotificationService(JavaMailSender sender) {
return new EmailNotificationService(sender);
}
@Bean
@ConditionalOnMissingBean(NotificationService.class)
public NotificationService noopNotificationService() {
return NotificationService.noOp();
}
}- Combine , profiles, and conditional annotations to orchestrate cross-cutting modules.
@Import
Additional worked examples (including tests and configuration wiring) are available in .
./references/examples.mdjava
@Configuration
@Import(DatabaseConfig.class)
public class MessagingConfig {
@Bean
@ConditionalOnProperty(name = "feature.notifications.enabled", havingValue = "true")
public NotificationService emailNotificationService(JavaMailSender sender) {
return new EmailNotificationService(sender);
}
@Bean
@ConditionalOnMissingBean(NotificationService.class)
public NotificationService noopNotificationService() {
return NotificationService.noOp();
}
}- 结合、配置文件和条件注解协调跨模块的配置。
@Import
更多完整示例(包括测试和配置注入)可在中查看。
./references/examples.mdBest Practices
最佳实践
- Prefer constructor injection for mandatory dependencies; allow Spring 4.3+ to infer on single constructors.
@Autowired - Encapsulate optional behavior inside dedicated adapters or providers instead of accepting pointers.
null - Keep service constructors lightweight; extract orchestrators when dependency counts exceed four.
- Favor domain interfaces in the domain layer and defer framework imports to infrastructure adapters.
- Document bean names and qualifiers in shared constants to avoid typo-driven mismatches.
- 强制依赖优先使用构造器注入;Spring 4.3+可自动推断单个构造器的。
@Autowired - 将可选行为封装在专用适配器或提供者中,而非接受空指针。
- 保持服务构造器轻量化;当依赖数量超过四个时,提取协调器。
- 领域层优先使用领域接口,将框架导入延迟到基础设施适配器中。
- 在共享常量中记录Bean名称和限定符,避免因拼写错误导致的不匹配。
Constraints and Warnings
约束与警告
- Avoid field injection and service locator patterns because they obscure dependencies and impede unit testing.
- Prevent circular dependencies by publishing domain events or extracting shared abstractions.
- Limit usage to performance-sensitive paths and record the deferred initialization risk.
@Lazy - Do not add profile-specific beans without matching integration tests that activate the profile.
- Ensure each optional collaborator has a deterministic default or feature-flag handling path.
- Never use on fields when constructor injection is possible.
@Autowired - Be aware that optional dependencies can lead to if not properly handled.
NullPointerException - Profile-specific beans can cause runtime errors if profiles are not correctly activated.
- 避免字段注入和服务定位器模式,因为它们会隐藏依赖关系并阻碍单元测试。
- 通过发布领域事件或提取共享抽象避免循环依赖。
- 仅在性能敏感路径中使用,并记录延迟初始化的风险。
@Lazy - 添加特定配置文件的Bean时,必须添加激活该配置文件的匹配集成测试。
- 确保每个可选协作者都有确定性的默认实现或功能标志处理路径。
- 只要可以使用构造器注入,就不要在字段上使用。
@Autowired - 注意如果处理不当,可选依赖可能导致。
NullPointerException - 如果配置文件未正确激活,特定配置文件的Bean可能导致运行时错误。
Reference Materials
参考资料
- extended documentation covering annotations, bean scopes, testing, and anti-pattern mitigations
- progressive examples from constructor injection basics to multi-module configurations
- curated excerpts from the official Spring Framework documentation (constructor vs setter guidance, conditional wiring)
- 涵盖注解、Bean作用域、测试和反模式缓解的扩展文档
- 从构造器注入基础到多模块配置的进阶示例
- 官方Spring Framework文档精选摘录(构造器与Setter注入指南、条件注入)
Related Skills
相关技能
- – service-layer orchestration patterns that rely on constructor injection.
spring-boot-crud-patterns - – controller-layer practices that assume explicit dependency wiring.
spring-boot-rest-api-standards - – Mockito-based testing patterns for constructor-injected services.
unit-test-service-layer
- – 依赖构造器注入的服务层协调模式。
spring-boot-crud-patterns - – 假设显式依赖注入的控制器层实践。
spring-boot-rest-api-standards - – 针对构造器注入服务的Mockito测试模式。
unit-test-service-layer