spring-boot-dependency-injection by giuseppe-trisciuoglio/developer-kit
npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit --skill spring-boot-dependency-injection使用此技能来保持 Spring Boot 的装配过程明确、可测试且可预测。
核心模型很简单:
此技能旨在塑造代码,使其在不依赖 Spring 容器进行每个单元测试的情况下,仍易于测试。
在以下情况使用此技能:
@Service、@Component、@Repository 或 @Configuration 类时典型的触发短语包括 spring dependency injection、constructor injection、、 和 。
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
replace field injectionqualifier vs primaryoptional bean对于每个类,识别:
必需的协作者应放在构造函数中。可选的协作者需要一个明确的策略,例如 ObjectProvider、条件 bean 或无操作实现。
对于应用服务和适配器:
final通常一个构造函数就足够了;在这种情况下,@Autowired 是不必要的。
好的选择包括:
ObjectProvider<T>@ConditionalOnProperty 或 @ConditionalOnMissingBean避免使用可为 null 的协作者,这会使运行时行为变得模糊。
当多个 bean 共享相同类型时:
@Primary@Qualifier如果选择规则变得复杂,请将它们移到专用的配置类中,而不是分散在各个服务中。
在以下情况使用 @Configuration 和 @Bean 方法:
业务服务不应知道基础设施协作者是如何实例化的。
按此顺序进行测试:
@SpringBootTest这可以使故障定位,并使依赖问题显而易见。
@Service
public class UserService {
private final UserRepository userRepository;
private final EmailSender emailSender;
public UserService(UserRepository userRepository, EmailSender emailSender) {
this.userRepository = userRepository;
this.emailSender = emailSender;
}
public User register(UserRegistrationRequest request) {
User user = userRepository.save(User.from(request));
emailSender.sendWelcome(user);
return user;
}
}
此类易于在单元测试中直接使用模拟对象进行实例化。
@Service
public class ReportService {
private final ReportRepository reportRepository;
private final NotificationGateway notificationGateway;
public ReportService(
ReportRepository reportRepository,
ObjectProvider<NotificationGateway> notificationGatewayProvider
) {
this.reportRepository = reportRepository;
this.notificationGateway = notificationGatewayProvider.getIfAvailable(NotificationGateway::noOp);
}
}
这使得可选行为明确,而无需在类的其余部分处理 null。
@Configuration
public class PaymentConfiguration {
@Bean
@Primary
PaymentGateway stripeGateway() {
return new StripePaymentGateway();
}
@Bean
@Qualifier("fallbackGateway")
PaymentGateway mockGateway() {
return new MockPaymentGateway();
}
}
对默认路径使用 @Primary,仅在需要特定变体时使用 @Qualifier。
@Lazy 解决的装配技巧。references/reference.mdreferences/examples.mdreferences/spring-official-dependency-injection.mdspring-boot-crud-patternsspring-boot-rest-api-standardsunit-test-service-layer每周安装次数
360
代码仓库
GitHub 星标数
173
首次出现
2026 年 2 月 3 日
安全审计
安装于
claude-code278
gemini-cli275
opencode274
codex270
cursor262
github-copilot255
Use this skill to keep Spring Boot wiring explicit, testable, and predictable.
The core model is simple:
This skill is about shaping code so it remains easy to test without depending on the Spring container for every unit test.
Use this skill when:
@Service, @Component, @Repository, or @Configuration classTypical trigger phrases include spring dependency injection, constructor injection, replace field injection, qualifier vs primary, and optional bean.
For each class, identify:
Mandatory collaborators belong in the constructor. Optional ones need an explicit strategy such as ObjectProvider, conditional beans, or a no-op implementation.
For application services and adapters:
finalA single constructor is usually enough; @Autowired is unnecessary in that case.
Good options include:
ObjectProvider<T> when lazy access is useful@ConditionalOnProperty or @ConditionalOnMissingBean when wiring should change by configurationAvoid nullable collaborators that leave runtime behavior ambiguous.
When multiple beans share the same type:
@Primary for the default implementation@Qualifier for named variantsIf selection rules become complex, move them into a dedicated configuration class instead of spreading them across services.
Use @Configuration and @Bean methods when:
Business services should not know how infrastructure collaborators are instantiated.
Test in this order:
@SpringBootTest only when container-wide wiring must be provenThis keeps failures localized and makes dependency problems obvious.
@Service
public class UserService {
private final UserRepository userRepository;
private final EmailSender emailSender;
public UserService(UserRepository userRepository, EmailSender emailSender) {
this.userRepository = userRepository;
this.emailSender = emailSender;
}
public User register(UserRegistrationRequest request) {
User user = userRepository.save(User.from(request));
emailSender.sendWelcome(user);
return user;
}
}
This class is easy to instantiate directly in a unit test with mocks.
@Service
public class ReportService {
private final ReportRepository reportRepository;
private final NotificationGateway notificationGateway;
public ReportService(
ReportRepository reportRepository,
ObjectProvider<NotificationGateway> notificationGatewayProvider
) {
this.reportRepository = reportRepository;
this.notificationGateway = notificationGatewayProvider.getIfAvailable(NotificationGateway::noOp);
}
}
This keeps optional behavior explicit without leaking null handling through the rest of the class.
@Configuration
public class PaymentConfiguration {
@Bean
@Primary
PaymentGateway stripeGateway() {
return new StripePaymentGateway();
}
@Bean
@Qualifier("fallbackGateway")
PaymentGateway mockGateway() {
return new MockPaymentGateway();
}
}
Use @Primary for the default path and @Qualifier only where a specific variant is required.
@Lazy.references/reference.mdreferences/examples.mdreferences/spring-official-dependency-injection.mdspring-boot-crud-patternsspring-boot-rest-api-standardsunit-test-service-layerWeekly Installs
360
Repository
GitHub Stars
173
First Seen
Feb 3, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
claude-code278
gemini-cli275
opencode274
codex270
cursor262
github-copilot255
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
106,200 周安装