Develop and maintain Spring Boot applications with Maven, following best practices for project structure, dependencies, and workflows.
A comprehensive skill for developing Spring Boot applications with Maven, Java 21, and modern development tools. This skill provides guidance on project structure, build workflows, component organization, and best practices for Spring Boot development.
This skill helps you build and maintain Spring Boot web applications following industry-standard patterns and conventions. It covers:
1. **Organize packages following Spring Boot conventions:**
- Place all components under the root package (e.g., `com.example.app`)
- Use sub-packages for logical grouping: `controller`, `service`, `repository`, `config`, `model`
- Ensure the main application class is in the root package for component scanning
2. **Configure Maven properly:**
- Use Spring Boot parent POM for dependency management
- Configure Lombok annotation processor in `maven-compiler-plugin`
- Follow standard Maven directory layout: `src/main/java`, `src/test/java`, `src/main/resources`
3. **Set up configuration files:**
- Primary configuration in `src/main/resources/application.properties`
- Static assets in `src/main/resources/static/`
- Templates in `src/main/resources/templates/`
1. **Use Maven wrapper for all build commands:**
- Windows: Use `.\mvnw.cmd` for all Maven operations
- Unix/Linux: Use `./mvnw` for all Maven operations
- Clean and compile: `.\mvnw.cmd clean compile`
- Run application: `.\mvnw.cmd spring-boot:run`
- Run tests: `.\mvnw.cmd test`
- Package: `.\mvnw.cmd package`
2. **Enable hot reload during development:**
- Ensure Spring Boot DevTools is in dependencies
- Changes to classes will trigger automatic restart
- Simply recompile in your IDE to see changes
3. **Add new Spring components correctly:**
- Controllers: Annotate with `@RestController` or `@Controller`
- Services: Annotate with `@Service`
- Repositories: Annotate with `@Repository`
- Configuration: Annotate with `@Configuration`
- All components must be in or under the root package for auto-discovery
1. **Add common Spring Boot starters as needed:**
- Web APIs: `spring-boot-starter-web` (already included)
- Database access: `spring-boot-starter-data-jpa`
- Security: `spring-boot-starter-security`
- Validation: `spring-boot-starter-validation`
2. **Use Lombok for reducing boilerplate:**
- `@Data` for getters, setters, toString, equals, hashCode
- `@Builder` for builder pattern
- `@Slf4j` for logging
- `@RequiredArgsConstructor` for dependency injection
- Ensure annotation processing is enabled in your IDE
3. **Include proper test dependencies:**
- `spring-boot-starter-test` provides JUnit 5, Mockito, AssertJ
- Use `@SpringBootTest` for integration tests
- Use `@WebMvcTest` for controller tests
1. **Create REST controllers:**
- Place in `controller` sub-package
- Use `@RestController` annotation
- Define request mappings with `@GetMapping`, `@PostMapping`, etc.
- Return DTOs or domain objects (automatically serialized to JSON)
2. **Implement service layer:**
- Place business logic in `@Service` classes
- Inject services into controllers using constructor injection
- Keep controllers thin, delegate to services
3. **Handle configuration:**
- Use `application.properties` for environment-specific settings
- Define server port, logging levels, database connections
- Use `@ConfigurationProperties` for type-safe configuration
1. **Write integration tests:**
- Use `@SpringBootTest` to load full application context
- Test REST endpoints with `MockMvc` or `TestRestTemplate`
- Verify business logic end-to-end
2. **Write unit tests:**
- Use `@WebMvcTest` for controller tests
- Mock service dependencies with Mockito
- Test individual components in isolation
3. **Maintain test coverage:**
- Add tests for new features
- Run `.\mvnw.cmd test` before committing
- Ensure basic context loading test passes
```java
package com.example.app.controller;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/users")
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
return userService.findById(id);
}
@PostMapping
public User createUser(@RequestBody User user) {
return userService.save(user);
}
}
```
```java
package com.example.app.model;
import lombok.Data;
import lombok.Builder;
@Data
@Builder
public class User {
private Long id;
private String name;
private String email;
}
```
```java
package com.example.app;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.web.client.TestRestTemplate;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class UserControllerIntegrationTest {
@Autowired
private TestRestTemplate restTemplate;
@Test
void testGetUser() {
User user = restTemplate.getForObject("/api/users/1", User.class);
assertNotNull(user);
}
}
```
Leave a review
No reviews yet. Be the first to review this skill!
# Download SKILL.md from killerskills.ai/api/skills/spring-boot-project-development/raw