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

java-expertJava expert 搜索

Agent Skill

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

总安装

1,854

周安装

75

GitHub Stars

25

下载量

582
CodexClaudeCursorGemini CLI

安装说明

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

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

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

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

命令行安装

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

skills.shnpx skills
npx skills add https://github.com/oimiragieo/agent-studio --skill java-expert

简介

java-expert 辅助 Java 项目开发、Spring 生态和后端工程实践,适合分析类结构和设计接口。

  • 适用于整理服务分层、生成测试或检查代码坏味道的场景。
  • 通过 npx skills add 命令从 GitHub 安装,使用时需结合项目已有架构和依赖版本。
  • 涉及数据库或框架配置时,应先确认运行环境和回归测试范围。
  • 适用宿主包括 Codex、Claude、Cursor、Gemini CLI,接入前应确认版本、权限和运行环境要求。

SKILL.md

Java Expert

Virtual Threads (Project Loom)

  • Lightweight threads that dramatically improve scalability for I/O-bound applications
  • Use Executors.newVirtualThreadPerTaskExecutor() for thread pools
  • Perfect for web applications with many concurrent connections
  • Spring Boot 3.2+ supports virtual threads via configuration
// Enable virtual threads in Spring Boot 3.2+
// application.properties
spring.threads.virtual.enabled=true

// Or programmatically
@Bean
public TomcatProtocolHandlerCustomizer<?> protocolHandlerVirtualThreadExecutorCustomizer() {
    return protocolHandler -> {
        protocolHandler.setExecutor(Executors.newVirtualThreadPerTaskExecutor());
    };
}

// Using virtual threads directly
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
    executor.submit(() -> {
        // I/O-bound task
        Thread.sleep(1000);
        return "result";
    });
}

Pattern Matching

  • Pattern matching for switch (Java 21)
  • Record patterns
  • Destructuring with pattern matching
// Pattern matching for switch
String result = switch (obj) {
    case String s -> "String: " + s;
    case Integer i -> "Integer: " + i;
    case Long l -> "Long: " + l;
    case null -> "null";
    default -> "Unknown";
};

// Record patterns
record Point(int x, int y) {}

if (obj instanceof Point(int x, int y)) {
    System.out.println("x: " + x + ", y: " + y);
}

Records

  • Immutable data carriers
  • Automatically generates constructor, getters, equals(), hashCode(), toString()
public record UserDTO(String name, String email, LocalDate birthDate) {
    // Compact constructor for validation
    public UserDTO {
        if (name == null || name.isBlank()) {
            throw new IllegalArgumentException("Name cannot be blank");
        }
    }
}

Sealed Classes

  • Restrict which classes can extend/implement
  • Provides exhaustive pattern matching
public sealed interface Result<T> permits Success, Failure {
    record Success<T>(T value) implements Result<T> {}
    record Failure<T>(String error) implements Result<T> {}
}

Spring Boot 3.x Best Practices (2026)

Framework Setup:

  • Java 21+ as baseline (virtual threads, pattern matching)
  • Spring Boot 3.2+ (latest stable)
  • Spring Framework 6.x
  • Jakarta EE (not javax.*) - namespace change

Project Structure (Layered Architecture):

src/main/java/com/example/app/
├── controller/         # REST endpoints (RestController)
├── service/           # Business logic (Service)
│   └── impl/         # Service implementations
├── repository/        # Data access (Repository)
├── model/
│   ├── entity/       # JPA entities
│   └── dto/          # Data Transfer Objects
├── config/           # Configuration classes
├── exception/        # Custom exceptions and handlers
└── util/             # Utility classes

Controller Layer (RestController):

  • Handle HTTP requests/responses only
  • Delegate business logic to services
  • Use DTOs for request/response bodies
  • Never directly inject repositories
@RestController
@RequestMapping("/api/users")
@RequiredArgsConstructor
public class UserController {
    private final UserService userService;

    @GetMapping("/{id}")
    public ResponseEntity<UserDTO> getUser(@PathVariable Long id) {
        UserDTO user = userService.findById(id);
        return ResponseEntity.ok(user);
    }

    @PostMapping
    public ResponseEntity<UserDTO> createUser(@Valid @RequestBody CreateUserDTO dto) {
        UserDTO created = userService.create(dto);
        return ResponseEntity.status(HttpStatus.CREATED).body(created);
    }
}

Service Layer:

  • Contains business logic
  • Uses repositories for data access
  • Converts between entities and DTOs
  • Annotated with @Service
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class UserServiceImpl implements UserService {
    private final UserRepository userRepository;
    private final ModelMapper modelMapper;

    @Override
    public UserDTO findById(Long id) {
        User user = userRepository.findById(id)
            .orElseThrow(() -> new UserNotFoundException(id));
        return modelMapper.map(user, UserDTO.class);
    }

    @Override
    @Transactional
    public UserDTO create(CreateUserDTO dto) {
        User user = modelMapper.map(dto, User.class);
        User saved = userRepository.save(user);
        return modelMapper.map(saved, UserDTO.class);
    }
}

Repository Layer (Spring Data JPA):

  • Extends JpaRepository<Entity, ID>
  • Define custom query methods
  • Use @Query for complex queries
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    Optional<User> findByEmail(String email);

    @Query("SELECT u FROM User u WHERE u.createdAt > :date")
    List<User> findRecentUsers(@Param("date") LocalDateTime date);

    // Projection for performance
    @Query("SELECT new com.example.dto.UserSummaryDTO(u.id, u.name, u.email) FROM User u")
    List<UserSummaryDTO> findAllSummaries();
}

JPA/Hibernate Best Practices

Entity Design:

  • Use @Entity and @Table annotations
  • Always define @Id with generation strategy
  • Use @Column for constraints and mappings
  • Implement equals() and hashCode() based on business key
@Entity
@Table(name = "users")
@Getter @Setter
@NoArgsConstructor
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

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

    @Column(nullable = false)
    private String name;

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Order> orders = new ArrayList<>();

    @CreatedDate
    @Column(nullable = false, updatable = false)
    private LocalDateTime createdAt;

    @LastModifiedDate
    private LocalDateTime updatedAt;
}

Performance Optimization:

  • Use @EntityGraph or JOIN FETCH to prevent N+1 queries
  • Lazy load associations by default
  • Use pagination for large result sets
  • Define proper indexes in database
@Query("SELECT u FROM User u JOIN FETCH u.orders WHERE u.id = :id")
Optional<User> findByIdWithOrders(@Param("id") Long id);

// Pagination
Page<User> findAll(Pageable pageable);

Testing (JUnit 5 + Mockito)

Unit Testing Services:

@ExtendWith(MockitoExtension.class)
class UserServiceImplTest {
    @Mock
    private UserRepository userRepository;

    @Mock
    private ModelMapper modelMapper;

    @InjectMocks
    private UserServiceImpl userService;

    @Test
    void findById_WhenUserExists_ReturnsUserDTO() {
        // Given
        Long userId = 1L;
        User user = new User();
        user.setId(userId);
        UserDTO expectedDTO = new UserDTO();

        when(userRepository.findById(userId)).thenReturn(Optional.of(user));
        when(modelMapper.map(user, UserDTO.class)).thenReturn(expectedDTO);

        // When
        UserDTO result = userService.findById(userId);

        // Then
        assertNotNull(result);
        verify(userRepository).findById(userId);
        verify(modelMapper).map(user, UserDTO.class);
    }
}

Integration Testing (Spring Boot Test):

@SpringBootTest
@AutoConfigureMockMvc
@Transactional
class UserControllerIntegrationTest {
    @Autowired
    private MockMvc mockMvc;

    @Autowired
    private ObjectMapper objectMapper;

    @Test
    void createUser_WithValidData_ReturnsCreated() throws Exception {
        CreateUserDTO dto = new CreateUserDTO("John Doe", "john@example.com");

        mockMvc.perform(post("/api/users")
                .contentType(MediaType.APPLICATION_JSON)
                .content(objectMapper.writeValueAsString(dto)))
            .andExpect(status().isCreated())
            .andExpect(jsonPath("$.name").value("John Doe"));
    }
}

Build Tools (Maven & Gradle)

Maven (pom.xml):

<properties>
    <java.version>21</java.version>
    <spring-boot.version>3.2.0</spring-boot.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-validation</artifactId>
    </dependency>
</dependencies>

Gradle (build.gradle):

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.2.0'
    id 'io.spring.dependency-management' version '1.1.4'
}

java {
    sourceCompatibility = JavaVersion.VERSION_21
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-validation'
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

Exception Handling

Global Exception Handler:

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(UserNotFoundException.class)
    public ResponseEntity<ErrorResponse> handleUserNotFound(UserNotFoundException ex) {
        ErrorResponse error = new ErrorResponse(
            "USER_NOT_FOUND",
            ex.getMessage(),
            LocalDateTime.now()
        );
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error);
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<ErrorResponse> handleValidation(MethodArgumentNotValidException ex) {
        Map<String, String> errors = ex.getBindingResult()
            .getFieldErrors()
            .stream()
            .collect(Collectors.toMap(
                FieldError::getField,
                FieldError::getDefaultMessage
            ));

        ErrorResponse error = new ErrorResponse(
            "VALIDATION_ERROR",
            "Invalid input",
            errors,
            LocalDateTime.now()
        );
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(error);
    }
}

Logging and Monitoring

Logging (SLF4J + Logback):

@Slf4j
@Service
public class UserServiceImpl implements UserService {

    public UserDTO findById(Long id) {
        log.debug("Finding user with id: {}", id);
        try {
            User user = userRepository.findById(id)
                .orElseThrow(() -> new UserNotFoundException(id));
            log.info("User found: {}", user.getEmail());
            return modelMapper.map(user, UserDTO.class);
        } catch (UserNotFoundException ex) {
            log.error("User not found with id: {}", id, ex);
            throw ex;
        }
    }
}

Actuator for Monitoring:

management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus
  endpoint:
    health:
      show-details: always

Iron Laws

  1. ALWAYS use constructor injection over field injection with @Autowired — field injection hides dependencies, makes testing harder, and creates partially-initialized objects that crash at runtime if the context isn't fully loaded.
  2. NEVER use Optional.get() without a preceding isPresent() check or orElse()/orElseThrow() — unconditional get() throws NoSuchElementException on empty optionals, silently defeating Optional's entire purpose.
  3. ALWAYS handle @Transactional boundaries explicitly — calling a transactional method from within the same class bypasses the proxy and runs without a transaction, causing silent data inconsistency.
  4. NEVER use @Async without a configured TaskExecutor — Spring's default @Async executor uses a single-thread pool; concurrent async calls queue up and defeat parallelism.
  5. ALWAYS use @ControllerAdvice with specific exception types for error handling — catching Exception globally hides root causes; specific exception handlers produce correct HTTP status codes and meaningful error responses.

Anti-Patterns

Anti-PatternWhy It FailsCorrect Approach
Field injection with @AutowiredHidden dependencies; untestable without Spring context; null in unit testsConstructor injection; all required dependencies declared as final fields
Optional.get() without checkNoSuchElementException at runtime; defeats Optional's null-safety contractUse orElseThrow(), orElse(), or map()/flatMap() chains
@Transactional on same-class method callsSpring proxy bypassed; method runs outside transaction; data integrity lostMove transactional methods to a separate service bean; inject and call from outside
Default @Async thread poolSingle-thread pool queues all tasks; async calls run sequentiallyConfigure ThreadPoolTaskExecutor with pool size, queue, and rejection policy
Global @ExceptionHandler(Exception.class)Swallows specific exceptions; all errors return same generic 500 responseMap specific exception types to HTTP status codes; use @ResponseStatus annotations

Consolidated Skills

This expert skill consolidates 1 individual skills:

  • java-expert

Memory Protocol (MANDATORY)

Before starting:

cat .claude/context/memory/learnings.md

After completing: Record any new patterns or exceptions discovered.

ASSUME INTERRUPTION: Your context may reset. If it's not in memory, it didn't happen.

适合场景

01

用户想查找某类 Agent Skill 时

02

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

03

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

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

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

能力 4

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

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

平台分布

Codex

33.48%
按下载量换算195

Claude

30.08%
按下载量换算175

Cursor

19.23%
按下载量换算112

Gemini CLI

8.63%
按下载量换算50

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

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

来源信息

继续浏览同类 Skills