Install
$ agentstack add skill-versoxbt-claude-initial-setup-spring-boot-patterns ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Spring Boot Patterns
Core patterns for building production-ready Spring Boot applications.
When to Use
- User is setting up a Spring Boot project
- User asks about @Component, @Service, @Repository usage
- User needs dependency injection patterns
- User is configuring profiles for dev/staging/prod
- User asks about externalized configuration or actuator
Core Patterns
Stereotype Annotations -- Layer Separation
Use the correct annotation for each architectural layer. Spring applies different behaviors to each.
@Repository // Data access -- translates persistence exceptions
public class UserRepository {
private final JdbcTemplate jdbc;
public UserRepository(JdbcTemplate jdbc) { this.jdbc = jdbc; }
public Optional findById(Long id) {
return jdbc.query("SELECT * FROM users WHERE id = ?",
new BeanPropertyRowMapper<>(User.class), id).stream().findFirst();
}
}
@Service // Business logic -- transactional boundaries live here
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) { this.userRepository = userRepository; }
@Transactional
public User createUser(CreateUserRequest request) {
return userRepository.save(new User(request.name(), request.email()));
}
}
@RestController // Web layer -- handles HTTP requests
@RequestMapping("/api/v1/users")
public class UserController {
private final UserService userService;
public UserController(UserService userService) { this.userService = userService; }
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public UserResponse createUser(@Valid @RequestBody CreateUserRequest request) {
return UserResponse.from(userService.createUser(request));
}
}
Constructor Injection
Always use constructor injection. It makes dependencies explicit, supports immutability, and works with final fields. Avoid field injection with @Autowired.
@Service
public class OrderService {
private final OrderRepository orderRepository;
private final PaymentGateway paymentGateway;
private final NotificationService notificationService;
// Single constructor -- @Autowired is implicit, no annotation needed
public OrderService(
OrderRepository orderRepository,
PaymentGateway paymentGateway,
NotificationService notificationService) {
this.orderRepository = orderRepository;
this.paymentGateway = paymentGateway;
this.notificationService = notificationService;
}
}
Profiles -- Environment-Specific Configuration
Use profiles to swap implementations and configuration per environment.
# application.yml -- shared defaults
spring:
application:
name: my-service
---
# application-dev.yml
spring:
datasource:
url: jdbc:h2:mem:devdb
driver-class-name: org.h2.Driver
jpa:
show-sql: true
---
# application-prod.yml
spring:
datasource:
url: jdbc:postgresql://${DB_HOST}:5432/${DB_NAME}
username: ${DB_USER}
password: ${DB_PASSWORD}
jpa:
show-sql: false
Profile-specific beans:
@Configuration
public class StorageConfig {
@Bean
@Profile("dev")
public StorageService localStorageService() {
return new LocalFileStorageService("/tmp/uploads");
}
@Bean
@Profile("prod")
public StorageService s3StorageService(S3Client s3Client) {
return new S3StorageService(s3Client);
}
}
@ConfigurationProperties -- Type-Safe Configuration
Bind external configuration to strongly-typed POJOs. Prefer this over scattered @Value annotations.
@ConfigurationProperties(prefix = "app.mail")
public record MailProperties(
String host,
int port,
String fromAddress,
Duration timeout,
RetryProperties retry
) {
public record RetryProperties(int maxAttempts, Duration delay) {}
}
app:
mail:
host: smtp.example.com
port: 587
from-address: noreply@example.com
timeout: 5s
retry:
max-attempts: 3
delay: 2s
Enable it:
@SpringBootApplication
@EnableConfigurationProperties(MailProperties.class)
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Actuator -- Production Monitoring
Expose health checks, metrics, and application info for monitoring systems.
# application.yml
management:
endpoints:
web:
exposure:
include: health,info,metrics,prometheus
endpoint:
health:
show-details: when-authorized
health:
db:
enabled: true
redis:
enabled: true
Custom health indicator:
@Component
public class PaymentGatewayHealthIndicator implements HealthIndicator {
private final PaymentGateway gateway;
public PaymentGatewayHealthIndicator(PaymentGateway gateway) { this.gateway = gateway; }
@Override
public Health health() {
try {
return gateway.ping()
? Health.up().withDetail("gateway", "reachable").build()
: Health.down().withDetail("gateway", "unreachable").build();
} catch (Exception e) { return Health.down(e).build(); }
}
}
Anti-Patterns
- Field injection with @Autowired -- Makes dependencies hidden, prevents immutability, and breaks testing. Use constructor injection instead.
- Business logic in controllers -- Controllers should only handle HTTP concerns (request parsing, response formatting). Delegate to services.
- Catching all exceptions in controllers -- Use
@ControllerAdvicewith@ExceptionHandlerfor centralized exception handling. - Using @Component for everything -- Use the specific stereotype (@Service, @Repository, @Controller) so Spring applies the correct behavior (transaction proxies, exception translation).
- Hardcoding configuration values -- Use @ConfigurationProperties or environment variables. Never hardcode URLs, credentials, or environment-specific values.
Quick Reference
Stereotype annotations:
@Component -- Generic Spring-managed bean
@Service -- Business logic layer
@Repository -- Data access layer (exception translation)
@Controller -- Web layer (returns views)
@RestController -- Web layer (returns JSON)
Configuration:
@ConfigurationProperties -- Type-safe config binding
@Value("${key}") -- Single value injection
@Profile("dev") -- Environment-specific bean
Actuator endpoints:
/actuator/health -- Application health
/actuator/info -- Application info
/actuator/metrics -- Micrometer metrics
/actuator/prometheus -- Prometheus-format metrics
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: VersoXBT
- Source: VersoXBT/claude-initial-setup
- License: MIT
- Homepage: https://github.com/VersoXBT/claude-initial-setup#installation
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.