# Spring Boot Patterns

> >

- **Type:** Skill
- **Install:** `agentstack add skill-versoxbt-claude-initial-setup-spring-boot-patterns`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [VersoXBT](https://agentstack.voostack.com/s/versoxbt)
- **Installs:** 0
- **Category:** [AI & ML](https://agentstack.voostack.com/c/ai-and-ml)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [VersoXBT](https://github.com/VersoXBT)
- **Source:** https://github.com/VersoXBT/claude-initial-setup/tree/main/skills/java/spring-boot-patterns
- **Website:** https://github.com/VersoXBT/claude-initial-setup#installation

## Install

```sh
agentstack add skill-versoxbt-claude-initial-setup-spring-boot-patterns
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## 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.

```java
@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.

```java
@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.

```yaml
# 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:

```java
@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.

```java
@ConfigurationProperties(prefix = "app.mail")
public record MailProperties(
    String host,
    int port,
    String fromAddress,
    Duration timeout,
    RetryProperties retry
) {
    public record RetryProperties(int maxAttempts, Duration delay) {}
}
```

```yaml
app:
  mail:
    host: smtp.example.com
    port: 587
    from-address: noreply@example.com
    timeout: 5s
    retry:
      max-attempts: 3
      delay: 2s
```

Enable it:
```java
@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.

```yaml
# 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:

```java
@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 `@ControllerAdvice` with `@ExceptionHandler` for 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](https://github.com/VersoXBT)
- **Source:** [VersoXBT/claude-initial-setup](https://github.com/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.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-versoxbt-claude-initial-setup-spring-boot-patterns
- Seller: https://agentstack.voostack.com/s/versoxbt
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
