Generate Spring Boot components following modern Java best practices and team conventions
When generating or reviewing Spring Boot code, follow these best practices:
private final@RequiredArgsConstructor generate constructors when appropriate// Good
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
private final EmailService emailService;
}
// Avoid
@Service
public class UserService {
@Autowired
private UserRepository userRepository; // Field injection - avoid
}
Follow standard Spring Boot layering:
com.example.project/
├── controller/ # REST endpoints, @RestController
├── service/ # Business logic, @Service
├── repository/ # Data access, extends JpaRepository
├── model/ # JPA entities, @Entity
├── dto/ # Data transfer objects
├── config/ # Configuration classes, @Configuration
└── exception/ # Custom exceptions and @ControllerAdvice
ResponseEntity<T> for explicit status codes@Valid for request body validation/api/v1/users)@RestController
@RequestMapping("/api/v1/users")
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
@GetMapping("/{id}")
public ResponseEntity<UserDto> getUser(@PathVariable Long id) {
return userService.findById(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
@PostMapping
public ResponseEntity<UserDto> createUser(@Valid @RequestBody CreateUserRequest request) {
UserDto created = userService.create(request);
return ResponseEntity.status(HttpStatus.CREATED).body(created);
}
}
Optional<T> for potentially absent results@Transactional where needed@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
public Optional<User> findById(Long id) {
return userRepository.findById(id);
}
@Transactional
public User create(CreateUserRequest request) {
if (userRepository.existsByEmail(request.getEmail())) {
throw new UserAlreadyExistsException(request.getEmail());
}
User user = new User(request.getName(), request.getEmail());
return userRepository.save(user);
}
}
@Entity and @Table annotations@Id with generation strategy@Data, @NoArgsConstructor, @AllArgsConstructor@OneToMany, @ManyToOne, etc.@Entity
@Table(name = "users")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String name;
@Column(nullable = false, unique = true)
private String email;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
private List<Order> orders = new ArrayList<>();
}
For every component generated:
@WebMvcTest and MockMvc@ExtendWith(MockitoExtension.class) with mocks@DataJpaTest with test database@SpringBootTest for end-to-end scenarios@WebMvcTest(UserController.class)
class UserControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private UserService userService;
@Test
void getUser_WhenExists_ReturnsUser() throws Exception {
// Arrange
UserDto user = new UserDto(1L, "John Doe", "john@example.com");
when(userService.findById(1L)).thenReturn(Optional.of(user));
// Act & Assert
mockMvc.perform(get("/api/v1/users/1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.name").value("John Doe"));
}
}
@param, @return, and @throws tags/**
* Creates a new user in the system.
*
* @param request the user creation request containing name and email
* @return the created user with generated ID
* @throws UserAlreadyExistsException if a user with the email already exists
*/
@Transactional
public User create(CreateUserRequest request) {
// implementation
}
@ControllerAdvice for global exception handling@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(UserNotFoundException.class)
public ResponseEntity<ErrorResponse> handleUserNotFound(UserNotFoundException ex) {
ErrorResponse error = new ErrorResponse(
HttpStatus.NOT_FOUND.value(),
ex.getMessage()
);
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error);
}
}
application.yml over application.propertiesspring:
datasource:
url: jdbc:postgresql://localhost:5432/mydb
username: ${DB_USERNAME}
password: ${DB_PASSWORD}
jpa:
hibernate:
ddl-auto: validate
show-sql: false
This skill automatically activates when:
npx skills add kousen/Spring Boot Best Practices下载完整 Skill 目录,包含 SKILL.md 及所有相关文件
Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer