Token导航 LogoToken导航TokenDH.com
研究检索敏感数据github未标认证来源可访问许可证需确认审计通过

spring-boot-javaspring boot Java 搜索

Agent Skill

用于辅助 Java 项目开发、面向对象设计、Spring 生态、Maven 或 Gradle 依赖和后端工程实践。它适合让 Agent 分析类结构、设计接口、整理服务分层、生成测试或检查常见代码坏味道。使用时需要结合项目已有架构、包结构和依赖版本,不应只按通用教程改代码;涉及数据库、事务、并发或框架配置时,应先确认运行环境和回归测试范围。

总安装

196

周安装

8

GitHub Stars

8

下载量

63
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:spring-boot-java(spring boot Java 搜索)
来源仓库:https://github.com/ar4mirez/samuel
仓库路径:skills/spring-boot-java
安装命令:
npx skills add https://github.com/ar4mirez/samuel --skill spring-boot-java
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/ar4mirez/samuel --skill spring-boot-java

简介

针对 Java 语言特性的 Spring Boot 深度优化技巧集合。

  • 适用于泛型编程、注解处理器与模块化开发的高级应用。
  • 提供 Lombok 集成、Record 类型使用与密封类实践案例。
  • 元注解滥用可能增加编译期复杂度影响可读性。spring-boot-java 属于研究检索类 Skill,可作为该场景下的辅助能力补充。
  • 建议开启 -parameters 编译选项保留方法参数名信息。

SKILL.md

Spring Boot (Java) Guide

Applies to: Spring Boot 3.x, Java 17+, REST APIs, Microservices, Enterprise Applications

Core Principles

  1. Convention Over Configuration: Leverage Spring Boot auto-configuration; override only when necessary
  2. Layered Architecture: Controller -> Service -> Repository with clear separation of concerns
  3. DTOs at Boundaries: Never expose JPA entities in API responses; use records as DTOs
  4. Constructor Injection: Use @RequiredArgsConstructor or explicit constructors; never field injection
  5. Externalized Config: All configuration via application.yml with profile-specific overrides
  6. Database Migrations: Schema changes through Flyway or Liquibase; never ddl-auto=update in production

Guardrails

Architecture Rules

  • Controllers handle HTTP concerns only (validation, status codes, response mapping)
  • Services contain business logic and transaction boundaries
  • Repositories handle data access; use Spring Data JPA query derivation first
  • Use @Transactional(readOnly = true) at service class level, @Transactional on write methods
  • Keep spring.jpa.open-in-view=false to prevent lazy loading surprises
  • Use ProblemDetail (RFC 7807) for all error responses

Dependency Injection

  • Prefer constructor injection with @RequiredArgsConstructor (Lombok) or explicit constructors
  • Never use @Autowired on fields
  • Use @Bean methods in @Configuration classes for third-party types
  • One @Configuration class per concern (SecurityConfig, WebConfig, CacheConfig)

REST API Conventions

  • Versioned paths: /api/v1/resources
  • Use proper HTTP methods: GET (read), POST (create), PUT (full update), PATCH (partial), DELETE
  • Return 201 Created with Location header for POST
  • Return 204 No Content for DELETE
  • Always validate request bodies with @Valid and Jakarta Bean Validation
  • Use @PageableDefault for list endpoints; never return unbounded collections
  • Document APIs with SpringDoc OpenAPI annotations (@Operation, @Tag, @ApiResponse)

Configuration

  • Use application.yml over application.properties
  • Environment-specific files: application-dev.yml, application-prod.yml
  • Reference secrets via environment variables: ${DB_PASSWORD:default}
  • Configure HikariCP pool sizes explicitly (do not rely on defaults)
  • Set server.error.include-message=never in production profiles

Project Structure

myproject/
├── src/main/java/com/example/myproject/
│   ├── MyProjectApplication.java       # @SpringBootApplication entry point
│   ├── config/
│   │   ├── SecurityConfig.java         # Spring Security filter chain
│   │   └── WebConfig.java              # CORS, interceptors, converters
│   ├── controller/
│   │   └── UserController.java         # REST endpoints
│   ├── service/
│   │   ├── UserService.java            # Interface
│   │   └── impl/
│   │       └── UserServiceImpl.java    # Implementation
│   ├── repository/
│   │   └── UserRepository.java         # JpaRepository interface
│   ├── model/
│   │   ├── entity/
│   │   │   └── User.java              # JPA entity
│   │   └── dto/
│   │       ├── UserRequest.java        # Input record with validation
│   │       └── UserResponse.java       # Output record
│   ├── exception/
│   │   ├── GlobalExceptionHandler.java # @RestControllerAdvice
│   │   └── ResourceNotFoundException.java
│   └── mapper/
│       └── UserMapper.java             # MapStruct interface
├── src/main/resources/
│   ├── application.yml
│   ├── application-dev.yml
│   ├── application-prod.yml
│   └── db/migration/
│       └── V1__create_users_table.sql  # Flyway migration
├── src/test/java/com/example/myproject/
│   ├── controller/
│   │   └── UserControllerTest.java     # MockMvc tests
│   ├── service/
│   │   └── UserServiceTest.java        # Mockito unit tests
│   └── integration/
│       └── UserIntegrationTest.java    # Testcontainers
├── pom.xml
└── Dockerfile
  • Service interfaces are optional for small projects; use them when multiple implementations exist
  • Place MapStruct mappers in a dedicated mapper/ package
  • Separate entity/ and dto/ under model/ to reinforce the boundary

Controller Pattern

@RestController
@RequestMapping("/api/v1/users")
@RequiredArgsConstructor
@Tag(name = "Users", description = "User management APIs")
public class UserController {

    private final UserService userService;

    @PostMapping
    @Operation(summary = "Create a new user")
    @ApiResponse(responseCode = "201", description = "User created")
    @ApiResponse(responseCode = "409", description = "Email conflict")
    public ResponseEntity<UserResponse> createUser(
            @Valid @RequestBody UserRequest request) {
        UserResponse response = userService.createUser(request);
        return ResponseEntity.status(HttpStatus.CREATED).body(response);
    }

    @GetMapping("/{id}")
    @Operation(summary = "Get user by ID")
    public ResponseEntity<UserResponse> getUserById(@PathVariable Long id) {
        return ResponseEntity.ok(userService.getUserById(id));
    }

    @GetMapping
    @Operation(summary = "List users with pagination")
    public ResponseEntity<Page<UserResponse>> getAllUsers(
            @PageableDefault(size = 20, sort = "id") Pageable pageable) {
        return ResponseEntity.ok(userService.getAllUsers(pageable));
    }

    @DeleteMapping("/{id}")
    @PreAuthorize("hasRole('ADMIN')")
    @Operation(summary = "Delete user (admin only)")
    public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
        userService.deleteUser(id);
        return ResponseEntity.noContent().build();
    }
}

Service Pattern

@Service
@RequiredArgsConstructor
@Slf4j
@Transactional(readOnly = true)
public class UserServiceImpl implements UserService {

    private final UserRepository userRepository;
    private final UserMapper userMapper;
    private final PasswordEncoder passwordEncoder;

    @Override
    @Transactional
    public UserResponse createUser(UserRequest request) {
        if (userRepository.existsByEmail(request.email())) {
            throw new DuplicateResourceException("User", "email", request.email());
        }

        User user = userMapper.toEntity(request);
        user.setPassword(passwordEncoder.encode(request.password()));
        User saved = userRepository.save(user);

        return userMapper.toResponse(saved);
    }

    @Override
    public UserResponse getUserById(Long id) {
        return userRepository.findById(id)
            .map(userMapper::toResponse)
            .orElseThrow(() -> new ResourceNotFoundException("User", "id", id));
    }

    @Override
    public Page<UserResponse> getAllUsers(Pageable pageable) {
        return userRepository.findAll(pageable).map(userMapper::toResponse);
    }

    @Override
    @Transactional
    public void deleteUser(Long id) {
        if (!userRepository.existsById(id)) {
            throw new ResourceNotFoundException("User", "id", id);
        }
        userRepository.deleteById(id);
    }
}

Repository Pattern

@Repository
public interface UserRepository extends JpaRepository<User, Long> {

    Optional<User> findByEmail(String email);

    boolean existsByEmail(String email);

    List<User> findByActiveTrue();

    Page<User> findByRole(User.Role role, Pageable pageable);

    @Query("SELECT u FROM User u WHERE u.active = true AND u.role = :role")
    List<User> findActiveUsersByRole(@Param("role") User.Role role);
}
  • Prefer Spring Data derived queries for simple lookups
  • Use @Query with JPQL for joins and complex filters
  • Use native queries only when JPQL is insufficient (bulk operations, database-specific functions)
  • Always return Optional for single-entity lookups
  • Use Page/Slice for paginated results

JPA Entity

@Entity
@Table(name = "users")
@Getter @Setter
@NoArgsConstructor @AllArgsConstructor @Builder
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false, unique = true)
    private String email;

    @Column(nullable = false)
    private String password;

    @Column(nullable = false)
    @Enumerated(EnumType.STRING)
    @Builder.Default
    private Role role = Role.USER;

    @CreationTimestamp
    @Column(updatable = false)
    private LocalDateTime createdAt;

    @UpdateTimestamp
    private LocalDateTime updatedAt;

    public enum Role { USER, ADMIN }
}

DTO Records with Validation

// Request DTO
@Builder
public record UserRequest(
    @NotBlank(message = "Email is required")
    @Email(message = "Invalid email format")
    String email,

    @NotBlank(message = "Password is required")
    @Size(min = 8, max = 100)
    String password,

    @NotBlank(message = "Name is required")
    @Size(min = 2, max = 100)
    String name
) {}

// Response DTO
@Builder
public record UserResponse(
    Long id,
    String email,
    String name,
    String role,
    LocalDateTime createdAt
) {}

Error Handling

@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    @ExceptionHandler(ResourceNotFoundException.class)
    public ProblemDetail handleNotFound(ResourceNotFoundException ex) {
        log.warn("Resource not found: {}", ex.getMessage());
        ProblemDetail problem = ProblemDetail.forStatusAndDetail(
            HttpStatus.NOT_FOUND, ex.getMessage());
        problem.setTitle("Resource Not Found");
        problem.setProperty("timestamp", Instant.now());
        return problem;
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ProblemDetail handleValidation(MethodArgumentNotValidException ex) {
        Map<String, String> errors = new HashMap<>();
        ex.getBindingResult().getAllErrors().forEach(error -> {
            String field = ((FieldError) error).getField();
            errors.put(field, error.getDefaultMessage());
        });
        ProblemDetail problem = ProblemDetail.forStatusAndDetail(
            HttpStatus.BAD_REQUEST, "Validation failed");
        problem.setTitle("Validation Error");
        problem.setProperty("timestamp", Instant.now());
        problem.setProperty("errors", errors);
        return problem;
    }

    @ExceptionHandler(Exception.class)
    public ProblemDetail handleUnexpected(Exception ex) {
        log.error("Unexpected error", ex);
        ProblemDetail problem = ProblemDetail.forStatusAndDetail(
            HttpStatus.INTERNAL_SERVER_ERROR, "An unexpected error occurred");
        problem.setTitle("Internal Server Error");
        problem.setProperty("timestamp", Instant.now());
        return problem;
    }
}

Security Configuration

@Configuration
@EnableWebSecurity
@EnableMethodSecurity  // enables @PreAuthorize for method-level access control
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        return http
            .csrf(AbstractHttpConfigurer::disable)  // disable for stateless REST APIs
            .sessionManagement(session ->
                session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/api-docs/**", "/swagger-ui/**").permitAll()
                .requestMatchers("/actuator/health", "/actuator/info").permitAll()
                .requestMatchers(HttpMethod.POST, "/api/v1/users").permitAll()
                .requestMatchers(HttpMethod.DELETE, "/api/v1/users/**").hasRole("ADMIN")
                .anyRequest().authenticated())
            .build();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder(12);  // cost factor 12: security/performance balance
    }
}

Testing Overview

Unit Tests (Mockito)

@ExtendWith(MockitoExtension.class)
@DisplayName("UserService")
class UserServiceTest {

    @Mock private UserRepository userRepository;
    @Mock private UserMapper userMapper;
    @Mock private PasswordEncoder passwordEncoder;
    @InjectMocks private UserServiceImpl userService;

    @Test
    @DisplayName("should create user with valid data")
    void shouldCreateUser() {
        when(userRepository.existsByEmail("test@example.com")).thenReturn(false);
        when(userMapper.toEntity(any())).thenReturn(new User());
        when(userRepository.save(any())).thenReturn(new User());
        when(userMapper.toResponse(any())).thenReturn(
            new UserResponse(1L, "test@example.com", "Test", "USER", null));

        UserResponse result = userService.createUser(
            new UserRequest("test@example.com", "Pass123!", "Test"));

        assertThat(result.email()).isEqualTo("test@example.com");
        verify(userRepository).save(any(User.class));
    }
}

Integration Tests (Testcontainers + MockMvc)

@SpringBootTest
@AutoConfigureMockMvc
@Testcontainers
class UserIntegrationTest {

    @Container
    static PostgreSQLContainer<?> postgres =
        new PostgreSQLContainer<>("postgres:15-alpine");

    @DynamicPropertySource
    static void configureProperties(DynamicPropertyRegistry registry) {
        registry.add("spring.datasource.url", postgres::getJdbcUrl);
        registry.add("spring.datasource.username", postgres::getUsername);
        registry.add("spring.datasource.password", postgres::getPassword);
    }

    @Autowired private MockMvc mockMvc;
    @Autowired private ObjectMapper objectMapper;

    @Test
    void shouldCreateUserViaApi() throws Exception {
        var request = new UserRequest("test@example.com", "Pass123!", "Test");
        mockMvc.perform(post("/api/v1/users")
                .contentType(MediaType.APPLICATION_JSON)
                .content(objectMapper.writeValueAsString(request)))
            .andExpect(status().isCreated())
            .andExpect(jsonPath("$.email").value("test@example.com"));
    }
}

Commands

# Create project via Spring Initializr
# https://start.spring.io/

# Build
./mvnw clean package

# Run
./mvnw spring-boot:run

# Run with profile
./mvnw spring-boot:run -Dspring-boot.run.profiles=dev

# Test
./mvnw test

# Test with coverage
./mvnw verify

# Format (with spotless plugin)
./mvnw spotless:apply

# Static analysis
./mvnw checkstyle:check

# Build Docker image (Spring Boot Buildpacks)
./mvnw spring-boot:build-image

# Native executable (GraalVM)
./mvnw -Pnative native:compile

Best Practices

DoDo Not
Constructor injection (@RequiredArgsConstructor)@Autowired on fields
@Transactional(readOnly = true) at class level@Transactional without readOnly at class level
DTOs (records) for API input/outputExpose JPA entities in responses
MapStruct for entity-DTO mappingManual mapping boilerplate
Pagination for all list endpointsUnbounded collection returns
ProblemDetail (RFC 7807) errorsCustom error formats
Flyway/Liquibase for migrationsddl-auto=update in production
Testcontainers for integration testsH2 as production substitute
open-in-view=falseLazy loading outside transactions
JPA batch inserts (hibernate.jdbc.batch_size)Individual saves in loops

Advanced Topics

For detailed patterns and advanced configurations, see:

  • references/patterns.md -- JPA advanced patterns, Security with JWT, WebFlux reactive, testing strategies, Actuator, deployment

External References

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

34.77%
按下载量换算22

Claude

32.14%
按下载量换算20

Cursor

19.25%
按下载量换算12

Gemini CLI

9.61%
按下载量换算6

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

敏感数据

该 Skill 可能接触密钥、Token、环境变量或敏感配置,应进入高风险复核队列,默认不自动发布。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills