
spring-boot-dependency-injection
by giuseppe-trisciuoglio
This repository is a starter kit for building "skills" and "agents" for Claude Code. The current content focuses on patterns, conventions, and agents for Java projects (Spring Boot, JUnit, LangChain4J), but the kit is designed to be extensible and multi-language (PHP, TypeScript, Python, etc.).
SKILL.md
name: spring-boot-dependency-injection description: Dependency injection workflow for Spring Boot projects covering constructor-first patterns, optional collaborator handling, bean selection, and validation practices. allowed-tools: Read, Write, Bash category: backend tags: [spring-boot, dependency-injection, constructor-injection, bean-configuration, autowiring, testing, java] version: 1.1.0 context7_library: /spring-projects/spring-framework context7_trust_score: 9.0
Spring Boot Dependency Injection
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.
When to Use
- Implement constructor injection for new
@Service,@Component, or@Repositoryclasses. - 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.
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
./gradlew testormvn testfor validation. - Load supporting material from
./references/when deeper patterns or samples are required.
Workflow
1. Map Collaborators
- Inventory constructors,
@Autowiredmembers, and configuration classes. - Classify dependencies as mandatory (must exist) or optional (feature-flagged, environment-specific).
2. Apply Constructor Injection
- Introduce constructors (or Lombok
@RequiredArgsConstructor) that accept every mandatory collaborator. - Mark injected fields
finaland protect invariants withObjects.requireNonNullif Lombok is not used. - Update
@Configurationor@Beanfactories to pass dependencies explicitly; consult./references/reference.mdfor canonical bean wiring.
3. Handle Optional Collaborators
- Supply setters annotated with
@Autowired(required = false)or injectObjectProvider<T>for lazy access. - Provide deterministic defaults (for example, no-op implementations) and document them inside configuration modules.
- Follow
./references/examples.md#example-2-setter-injection-for-optional-dependenciesfor a full workflow.
4. Resolve Bean Selection
- Choose
@Primaryfor dominant implementations and@Qualifierfor niche variants. - Use profiles, conditional annotations, or factory methods to isolate environment-specific wiring.
- Reference
./references/reference.md#conditional-bean-registrationfor conditional and profile-based samples.
5. Validate Wiring
- Write unit tests that instantiate classes manually with mocks to prove Spring-free testability.
- Add slice or integration tests (
@WebMvcTest,@DataJpaTest,@SpringBootTest) only after constructor contracts are validated. - Reuse patterns in
./references/reference.md#testing-with-dependency-injectionto select the proper test style.
Examples
Basic Constructor Injection
@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:
new UserService(mockRepo, mockEmailService);with no Spring context required.
Intermediate: Optional Dependency with Guarded Setter
@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
CacheService.noOp()to ensure deterministic behavior when the optional bean is absent.
Advanced: Conditional Configuration Across Modules
@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
@Import, profiles, and conditional annotations to orchestrate cross-cutting modules.
Additional worked examples (including tests and configuration wiring) are available in ./references/examples.md.
Best Practices
- Prefer constructor injection for mandatory dependencies; allow Spring 4.3+ to infer
@Autowiredon single constructors. - Encapsulate optional behavior inside dedicated adapters or providers instead of accepting
nullpointers. - 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.
Constraints
- 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
@Lazyusage to performance-sensitive paths and record the deferred initialization risk. - 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.
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)
Related Skills
spring-boot-crud-patterns– service-layer orchestration patterns that rely on constructor injection.spring-boot-rest-api-standards– controller-layer practices that assume explicit dependency wiring.unit-test-service-layer– Mockito-based testing patterns for constructor-injected services.
Score
Total Score
Based on repository quality metrics
SKILL.mdファイルが含まれている
ライセンスが設定されている
100文字以上の説明がある
GitHub Stars 100以上
1ヶ月以内に更新
10回以上フォークされている
オープンIssueが50未満
プログラミング言語が設定されている
1つ以上のタグが設定されている
Reviews
Reviews coming soon
