本文档按框架分类整理了Java开发中最常用的注解,涵盖Spring、Spring Boot、Redis、MySQL/JPA等框架,每个注解都配有详细说明和使用示例。


一、Spring Framework 核心注解

1.1 组件声明注解

注解 作用 使用位置
@Component 通用组件注解,标记类为Spring管理的Bean
@Service 标记业务逻辑层组件,语义更明确
@Repository 标记数据访问层组件,自动转换持久层异常
@Controller 标记Web控制器,用于MVC模式
@RestController 组合注解(@Controller + @ResponseBody),用于RESTful API
@Configuration 标记配置类,相当于XML配置文件

示例:

@Service
public class UserService {
    public User findById(Long id) {
        // 业务逻辑
        return userRepository.findById(id).orElse(null);
    }
}

@Repository
public class UserRepository {
    // 数据访问逻辑,自动转换SQL异常为Spring的DataAccessException
}

@RestController
@RequestMapping("/api/users")
public class UserController {
    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        return userService.findById(id);
    }
}

1.2 依赖注入注解

注解 作用 使用位置
@Autowired 按类型自动装配Bean 字段、构造器、Setter方法
@Qualifier 指定具体Bean名称,配合@Autowired使用 字段、参数
@Resource JSR-250标准注解,默认按名称注入 字段、Setter方法
@Value 注入配置属性值或SpEL表达式 字段、参数
@Inject JSR-330标准注解,类似@Autowired 字段、构造器、方法

示例:

@Service
public class OrderService {
    
    // 构造器注入(推荐方式)
    private final UserRepository userRepository;
    private final PaymentService paymentService;
    
    @Autowired
    public OrderService(UserRepository userRepository, 
                       @Qualifier("alipayService") PaymentService paymentService) {
        this.userRepository = userRepository;
        this.paymentService = paymentService;
    }
    
    @Value("${app.name:defaultName}")
    private String appName;
    
    @Value("#{systemProperties['java.home']}")
    private String javaHome;
}

// JSR-250 示例
public class NotificationService {
    @Resource(name = "emailService")
    private MessageService messageService;
}

1.3 作用域与生命周期注解

注解 作用 使用位置
@Scope 指定Bean作用域(singleton/prototype/request/session)
@PostConstruct 标记初始化方法,在依赖注入后执行 方法
@PreDestroy 标记销毁方法,在容器关闭前执行 方法
@Lazy 延迟初始化Bean 类、字段
@DependsOn 指定Bean初始化顺序依赖

示例:

@Component
@Scope("prototype")  // 每次请求创建新实例
@DependsOn("databaseConfig")  // 确保databaseConfig先初始化
public class PrototypeBean {
    
    @PostConstruct
    public void init() {
        System.out.println("Bean初始化完成");
    }
    
    @PreDestroy
    public void destroy() {
        System.out.println("Bean即将销毁");
    }
}

1.4 AOP相关注解

注解 作用 使用位置
@Aspect 标记切面类
@Pointcut 定义切点表达式 方法
@Before 前置通知 方法
@After 后置通知 方法
@AfterReturning 返回通知 方法
@AfterThrowing 异常通知 方法
@Around 环绕通知 方法

示例:

@Aspect
@Component
public class LoggingAspect {
    
    @Pointcut("execution(* com.example.service.*.*(..))")
    public void serviceLayer() {}
    
    @Before("serviceLayer()")
    public void logBefore(JoinPoint joinPoint) {
        System.out.println("调用方法: " + joinPoint.getSignature().getName());
    }
    
    @Around("serviceLayer()")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        Object result = joinPoint.proceed();
        long duration = System.currentTimeMillis() - start;
        System.out.println("方法执行耗时: " + duration + "ms");
        return result;
    }
}

二、Spring Boot 专属注解

2.1 启动与配置注解

注解 作用 使用位置
@SpringBootApplication 组合注解(@Configuration + @EnableAutoConfiguration + @ComponentScan) 主类
@EnableAutoConfiguration 启用自动配置机制
@ComponentScan 配置组件扫描路径
@SpringBootConfiguration 标记Spring Boot配置类
@EnableConfigurationProperties 启用@ConfigurationProperties配置类

示例:

@SpringBootApplication(
    scanBasePackages = {"com.example", "com.shared"},
    exclude = {DataSourceAutoConfiguration.class}  // 排除特定自动配置
)
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

2.2 属性配置注解

注解 作用 使用位置
@ConfigurationProperties 批量绑定配置属性到POJO
@PropertySource 指定自定义属性文件
@PropertySources 指定多个属性文件
@Profile 指定环境配置(dev/test/prod) 类、方法

示例:

// application.yml
# aliyun:
#   oss:
#     endpoint: oss-cn-hangzhou.aliyuncs.com
#     accessKeyId: your-id
#     accessKeySecret: your-secret

@Component
@ConfigurationProperties(prefix = "aliyun.oss")
public class OssProperties {
    private String endpoint;
    private String accessKeyId;
    private String accessKeySecret;
    // getters and setters
}

// 使用
@Service
public class OssService {
    @Autowired
    private OssProperties ossProperties;
}

// 多环境配置
@Configuration
@Profile("production")
public class ProductionConfig {
    // 生产环境特定配置
}

2.3 条件装配注解

注解 作用 使用位置
@ConditionalOnProperty 当配置属性满足条件时生效 类、方法
@ConditionalOnClass 当类路径存在指定类时生效 类、方法
@ConditionalOnMissingClass 当类路径不存在指定类时生效 类、方法
@ConditionalOnBean 当容器中存在指定Bean时生效 类、方法
@ConditionalOnMissingBean 当容器中不存在指定Bean时生效 类、方法
@ConditionalOnWebApplication 当是Web应用时生效 类、方法
@Conditional 自定义条件判断 类、方法

示例:

@Configuration
public class ConditionalConfig {
    
    @Bean
    @ConditionalOnProperty(name = "feature.cache.enabled", havingValue = "true")
    public CacheService cacheService() {
        return new RedisCacheService();
    }
    
    @Bean
    @ConditionalOnClass(name = "com.mysql.jdbc.Driver")
    @ConditionalOnMissingBean(DataSource.class)
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }
}

三、Spring Web MVC 注解

3.1 请求映射注解

注解 作用 使用位置
@RequestMapping 通用请求映射,可指定路径、方法、参数等 类、方法
@GetMapping 处理GET请求 方法
@PostMapping 处理POST请求 方法
@PutMapping 处理PUT请求 方法
@DeleteMapping 处理DELETE请求 方法
@PatchMapping 处理PATCH请求 方法

示例:

@RestController
@RequestMapping("/api/v1/users")
public class UserController {
    
    @GetMapping  // GET /api/v1/users
    public List<User> listUsers(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        return userService.findAll(page, size);
    }
    
    @GetMapping("/{id}")  // GET /api/v1/users/123
    public User getUser(@PathVariable Long id) {
        return userService.findById(id);
    }
    
    @PostMapping  // POST /api/v1/users
    public ResponseEntity<User> createUser(@Valid @RequestBody UserDTO userDTO) {
        User user = userService.create(userDTO);
        URI location = ServletUriComponentsBuilder
            .fromCurrentRequest()
            .path("/{id}")
            .buildAndExpand(user.getId())
            .toUri();
        return ResponseEntity.created(location).body(user);
    }
    
    @PutMapping("/{id}")  // PUT /api/v1/users/123
    public User updateUser(@PathVariable Long id, @RequestBody UserDTO userDTO) {
        return userService.update(id, userDTO);
    }
    
    @DeleteMapping("/{id}")  // DELETE /api/v1/users/123
    @ResponseStatus(HttpStatus.NO_CONTENT)
    public void deleteUser(@PathVariable Long id) {
        userService.delete(id);
    }
}

3.2 请求参数处理注解

注解 作用 使用位置
@PathVariable 从URL路径中提取变量 参数
@RequestParam 从查询参数中获取值 参数
@RequestBody 将请求体JSON/XML绑定到对象 参数
@ResponseBody 将返回值序列化为JSON/XML 类、方法
@RequestHeader 获取请求头信息 参数
@CookieValue 获取Cookie值 参数
@ModelAttribute 将表单数据绑定到模型对象 参数
@SessionAttribute 获取Session属性 参数

示例:

@PostMapping("/upload")
public ResponseEntity<String> uploadFile(
        @RequestParam("file") MultipartFile file,
        @RequestParam(required = false, defaultValue = "false") boolean overwrite,
        @RequestHeader("X-Request-ID") String requestId,
        @CookieValue(value = "sessionId", required = false) String sessionId) {
    
    // 处理文件上传
    return ResponseEntity.ok("File uploaded");
}

@GetMapping("/search")
public List<Product> search(
        @RequestParam Map<String, String> allParams,  // 获取所有查询参数
        @RequestParam MultiValueMap<String, String> multiParams) {  // 支持多值参数
    // 处理搜索逻辑
    return productService.search(allParams);
}

3.3 响应处理注解

注解 作用 使用位置
@ResponseStatus 指定响应状态码 类、方法、异常
@ExceptionHandler 处理特定异常 方法
@ControllerAdvice 全局异常处理类
@RestControllerAdvice 组合注解(@ControllerAdvice + @ResponseBody)
@CrossOrigin 配置跨域访问 类、方法

示例:

@RestControllerAdvice
public class GlobalExceptionHandler {
    
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public Map<String, String> handleValidationExceptions(MethodArgumentNotValidException ex) {
        Map<String, String> errors = new HashMap<>();
        ex.getBindingResult().getAllErrors().forEach((error) -> {
            String fieldName = ((FieldError) error).getField();
            String errorMessage = error.getDefaultMessage();
            errors.put(fieldName, errorMessage);
        });
        return errors;
    }
    
    @ExceptionHandler(ResourceNotFoundException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public ErrorResponse handleResourceNotFound(ResourceNotFoundException ex) {
        return new ErrorResponse(ex.getMessage(), LocalDateTime.now());
    }
}

@RestController
@CrossOrigin(origins = "http://localhost:3000", maxAge = 3600)
public class ProductController {
    // 控制器方法
}

四、数据验证注解(Bean Validation)

4.1 常用验证注解

注解 作用 适用类型
@NotNull 值不能为null 任意
@NotEmpty 字符串/集合不能为空(null或空) String, Collection, Map, Array
@NotBlank 字符串不能为空白(去空格后长度>0) String
@Size 长度/大小在指定范围内 String, Collection, Map, Array
@Min 数值最小值 Number
@Max 数值最大值 Number
@Range 数值在指定范围内 Number
@DecimalMin 十进制最小值 BigDecimal, BigInteger等
@DecimalMax 十进制最大值 BigDecimal, BigInteger等
@Positive 正数(>0) Number
@PositiveOrZero 非负数(>=0) Number
@Negative 负数(<0) Number
@NegativeOrZero 非正数(<=0) Number
@Digits 整数和小数位数限制 Number
@Past 过去日期 Date, LocalDate等
@Future 未来日期 Date, LocalDate等
@Pattern 正则表达式匹配 String
@Email 邮箱格式验证 String
@AssertTrue 必须为true Boolean
@AssertFalse 必须为false Boolean
@Valid 级联验证嵌套对象 对象
@Validated 分组验证(Spring扩展) 类、方法、参数

示例:

public class UserDTO {
    
    @NotBlank(message = "用户名不能为空")
    @Size(min = 3, max = 20, message = "用户名长度必须在3-20之间")
    @Pattern(regexp = "^[a-zA-Z0-9_]+$", message = "用户名只能包含字母、数字和下划线")
    private String username;
    
    @NotBlank(message = "邮箱不能为空")
    @Email(message = "邮箱格式不正确")
    private String email;
    
    @NotNull(message = "年龄不能为空")
    @Min(value = 18, message = "年龄必须大于等于18岁")
    @Max(value = 120, message = "年龄必须小于等于120岁")
    private Integer age;
    
    @NotBlank(message = "手机号不能为空")
    @Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
    private String phone;
    
    @DecimalMin(value = "0.00", inclusive = false, message = "余额必须大于0")
    @Digits(integer = 10, fraction = 2, message = "余额格式不正确")
    private BigDecimal balance;
    
    @Valid  // 级联验证
    @NotNull(message = "地址信息不能为空")
    private AddressDTO address;
    
    @NotEmpty(message = "至少选择一个角色")
    private List<String> roles;
}

// 控制器中使用
@RestController
public class UserController {
    
    @PostMapping("/users")
    public ResponseEntity<?> createUser(
            @Valid @RequestBody UserDTO userDTO,  // @Valid触发验证
            BindingResult bindingResult) {        // 获取验证结果
        
        if (bindingResult.hasErrors()) {
            List<String> errors = bindingResult.getFieldErrors()
                .stream()
                .map(e -> e.getField() + ": " + e.getDefaultMessage())
                .collect(Collectors.toList());
            return ResponseEntity.badRequest().body(errors);
        }
        
        // 保存用户
        return ResponseEntity.ok("用户创建成功");
    }
    
    // 分组验证示例
    @PutMapping("/users/{id}")
    public User updateUser(
            @PathVariable Long id,
            @Validated(UpdateGroup.class) @RequestBody UserDTO userDTO) {
        return userService.update(id, userDTO);
    }
}

// 验证分组接口
public interface UpdateGroup {}
public interface CreateGroup {}

五、Spring Data JPA 注解(MySQL等关系型数据库)

5.1 实体映射注解

注解 作用 使用位置
@Entity 标记类为JPA实体
@Table 指定映射的数据库表名及约束
@Id 标记主键字段 字段
@GeneratedValue 指定主键生成策略 字段
@Column 指定列属性(名称、长度、非空等) 字段
@Transient 标记字段不持久化到数据库 字段
@Enumerated 指定枚举存储方式(STRING/ORDINAL) 字段
@Temporal 指定日期类型映射(DATE/TIME/TIMESTAMP) 字段
@Lob 标记大对象字段(BLOB/CLOB) 字段
@Basic 基本映射配置,可指定延迟加载 字段

示例:

@Entity
@Table(
    name = "sys_user",
    uniqueConstraints = {
        @UniqueConstraint(columnNames = {"username"}, name = "uk_username"),
        @UniqueConstraint(columnNames = {"email"}, name = "uk_email")
    },
    indexes = {
        @Index(columnList = "created_time", name = "idx_created_time"),
        @Index(columnList = "status,username", name = "idx_status_username")
    }
)
public class User {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)  // MySQL自增
    private Long id;
    
    @Column(name = "username", nullable = false, length = 50)
    private String username;
    
    @Column(name = "email", nullable = false, length = 100)
    private String email;
    
    @Column(name = "age", nullable = true)
    private Integer age;
    
    @Enumerated(EnumType.STRING)  // 以字符串形式存储枚举
    @Column(name = "status", length = 20)
    private UserStatus status;
    
    @Column(name = "created_time", updatable = false)
    @CreationTimestamp  // Hibernate自动填充创建时间
    private LocalDateTime createdTime;
    
    @Column(name = "updated_time")
    @UpdateTimestamp    // Hibernate自动填充更新时间
    private LocalDateTime updatedTime;
    
    @Lob
    @Column(name = "avatar", columnDefinition = "LONGBLOB")
    private byte[] avatar;
    
    @Transient  // 不保存到数据库
    private String tempToken;
    
    // 枚举定义
    public enum UserStatus {
        ACTIVE, INACTIVE, SUSPENDED
    }
}

5.2 关系映射注解

注解 作用 使用位置
@OneToOne 一对一关系 字段
@OneToMany 一对多关系 字段
@ManyToOne 多对一关系 字段
@ManyToMany 多对多关系 字段
@JoinColumn 指定外键列 字段
@JoinTable 指定关联表(多对多) 字段
@MappedBy 指定关系的拥有方 字段
@Fetch 指定加载策略(EAGER/LAZY) 字段
@Cascade 指定级联操作 字段

示例:

@Entity
public class Department {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(name = "dept_name")
    private String name;
    
    // 一对多关系:一个部门有多个员工
    @OneToMany(mappedBy = "department", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<Employee> employees = new ArrayList<>();
}

@Entity
public class Employee {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(name = "emp_name")
    private String name;
    
    // 多对一关系:多个员工属于一个部门
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "dept_id", foreignKey = @ForeignKey(name = "fk_emp_dept"))
    private Department department;
    
    // 一对一关系
    @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinColumn(name = "profile_id")
    private EmployeeProfile profile;
    
    // 多对多关系:员工参与多个项目
    @ManyToMany
    @JoinTable(
        name = "employee_project",
        joinColumns = @JoinColumn(name = "employee_id"),
        inverseJoinColumns = @JoinColumn(name = "project_id")
    )
    private Set<Project> projects = new HashSet<>();
}

5.3 Spring Data Repository 注解

注解 作用 使用位置
@Repository 标记数据访问层 接口
@Query 自定义JPQL或原生SQL查询 方法
@Param 指定方法参数名称 参数
@Modifying 标记修改操作(update/delete) 方法
@Transactional 声明事务 方法、类
@Procedure 调用存储过程 方法
@Lock 指定悲观锁模式 方法

示例:

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    
    // 方法名派生查询
    List<User> findByUsernameContainingAndStatus(String username, UserStatus status);
    
    // 自定义JPQL查询
    @Query("SELECT u FROM User u WHERE u.email = :email AND u.status = :status")
    Optional<User> findByEmailAndStatus(@Param("email") String email, 
                                        @Param("status") UserStatus status);
    
    // 原生SQL查询
    @Query(value = "SELECT * FROM sys_user WHERE created_time > ?1", nativeQuery = true)
    List<User> findRecentUsers(LocalDateTime date);
    
    // 更新操作
    @Modifying
    @Transactional
    @Query("UPDATE User u SET u.status = :newStatus WHERE u.id = :userId")
    int updateStatus(@Param("userId") Long userId, @Param("newStatus") UserStatus newStatus);
    
    // 分页查询
    @Query("SELECT u FROM User u WHERE u.age >= :minAge")
    Page<User> findByMinAge(@Param("minAge") int minAge, Pageable pageable);
}

六、Spring Cache + Redis 注解

6.1 缓存核心注解

注解 作用 使用位置
@EnableCaching 启用Spring缓存抽象 配置类
@Cacheable 触发缓存读取,不存在则执行方法并缓存 方法
@CachePut 更新缓存(不检查缓存,直接执行方法) 方法
@CacheEvict 删除缓存 方法
@Caching 组合多个缓存操作 方法
@CacheConfig 类级别的缓存配置(统一指定cacheNames等)

示例:

@Configuration
@EnableCaching
public class CacheConfig {
    
    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
            .entryTtl(Duration.ofMinutes(10))  // 默认过期时间10分钟
            .serializeKeysWith(RedisSerializationContext.SerializationPair
                .fromSerializer(new StringRedisSerializer()))
            .serializeValuesWith(RedisSerializationContext.SerializationPair
                .fromSerializer(new GenericJackson2JsonRedisSerializer()));
        
        return RedisCacheManager.builder(connectionFactory)
            .cacheDefaults(config)
            .withCacheConfiguration("users", 
                RedisCacheConfiguration.defaultCacheConfig()
                    .entryTtl(Duration.ofHours(1)))  // users缓存1小时
            .transactionAware()
            .build();
    }
}

@Service
@CacheConfig(cacheNames = "users", keyGenerator = "customKeyGenerator")
public class UserService {
    
    // 查询缓存,key为"users::userId"
    @Cacheable(key = "'user:' + #userId", unless = "#result == null")
    public User getUserById(Long userId) {
        return userRepository.findById(userId).orElse(null);
    }
    
    // 更新缓存
    @CachePut(key = "'user:' + #user.id")
    public User updateUser(User user) {
        return userRepository.save(user);
    }
    
    // 删除缓存
    @CacheEvict(key = "'user:' + #userId")
    public void deleteUser(Long userId) {
        userRepository.deleteById(userId);
    }
    
    // 组合操作:更新用户同时删除用户列表缓存
    @Caching(
        put = @CachePut(key = "'user:' + #user.id"),
        evict = {
            @CacheEvict(cacheNames = "userList", allEntries = true),
            @CacheEvict(cacheNames = "statistics", key = "'userStats'")
        }
    )
    public User saveAndRefresh(User user) {
        return userRepository.save(user);
    }
    
    // 条件缓存:仅当用户状态为ACTIVE时缓存
    @Cacheable(key = "'activeUsers'", condition = "#status.name() == 'ACTIVE'")
    public List<User> findByStatus(UserStatus status) {
        return userRepository.findByStatus(status);
    }
}

6.2 Redis特定注解(Spring Data Redis)

注解 作用 使用位置
@RedisHash 标记实体为Redis Hash存储
@Id 标记Redis实体ID 字段
@Indexed 标记字段创建二级索引 字段
@TimeToLive 指定过期时间(秒) 字段
@Reference 引用其他Redis实体 字段

示例:

@RedisHash("products")  // 存储在Redis的Hash中,key前缀为"products"
public class Product {
    
    @Id
    private String id;
    
    @Indexed  // 创建索引,支持通过name查询
    private String name;
    
    @Indexed
    private String category;
    
    private BigDecimal price;
    
    @TimeToLive  // 过期时间(秒)
    private Long expiration;
}

@Repository
public interface ProductRepository extends CrudRepository<Product, String> {
    // 自动实现通过索引字段的查询
    List<Product> findByCategory(String category);
    List<Product> findByNameContaining(String name);
}

七、事务管理注解

注解 作用 使用位置
@Transactional 声明式事务管理 类、方法
@Propagation 指定事务传播行为(REQUIRED/REQUIRES_NEW等) 方法
@Isolation 指定事务隔离级别 方法
@Rollback 测试方法后回滚事务 测试方法
@Commit 测试方法后提交事务 测试方法

示例:

@Service
@Transactional(readOnly = true)  // 类级别默认只读
public class OrderService {
    
    @Transactional(
        propagation = Propagation.REQUIRED,      // 默认传播行为
        isolation = Isolation.READ_COMMITTED,    // 隔离级别
        timeout = 30,                            // 超时时间(秒)
        rollbackFor = {BusinessException.class},   // 指定回滚异常
        noRollbackFor = {IllegalArgumentException.class}  // 指定不回滚异常
    )
    public Order createOrder(OrderDTO dto) {
        // 1. 扣减库存
        inventoryService.deduct(dto.getProductId(), dto.getQuantity());
        
        // 2. 创建订单
        Order order = orderRepository.save(convertToEntity(dto));
        
        // 3. 扣减余额
        paymentService.charge(dto.getUserId(), dto.getAmount());
        
        return order;
    }
    
    // 需要新事务,挂起当前事务
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void saveLog(OrderLog log) {
        logRepository.save(log);
    }
    
    // 不支持事务,以非事务方式执行
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Order queryOrder(Long orderId) {
        return orderRepository.findById(orderId).orElse(null);
    }
}

// 测试中使用
@SpringBootTest
@Transactional  // 测试后回滚
public class OrderServiceTest {
    
    @Autowired
    private OrderService orderService;
    
    @Test
    @Rollback(false)  // 不回滚,保留测试数据
    public void testCreateOrder() {
        // 测试代码
    }
}

八、Spring Security 注解

注解 作用 使用位置
@EnableWebSecurity 启用Spring Security 配置类
@EnableMethodSecurity 启用方法级安全控制 配置类
@PreAuthorize 方法执行前权限验证(SpEL表达式) 方法
@PostAuthorize 方法执行后权限验证 方法
@PreFilter 方法执行前过滤集合参数 方法
@PostFilter 方法执行后过滤返回值 方法
@Secured JSR-250角色验证 方法、类
@RolesAllowed JSR-250角色允许 方法、类
@PermitAll 允许所有访问 方法、类
@DenyAll 拒绝所有访问 方法、类
@AuthenticationPrincipal 获取当前认证用户 参数

示例:

@Configuration
@EnableWebSecurity
@EnableMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig {
    // 安全配置
}

@RestController
public class AdminController {
    
    // 需要ADMIN角色
    @PreAuthorize("hasRole('ADMIN')")
    @GetMapping("/admin/users")
    public List<User> listAllUsers() {
        return userService.findAll();
    }
    
    // 需要ADMIN或MANAGER角色,且IP限制
    @PreAuthorize("hasAnyRole('ADMIN', 'MANAGER') and hasIpAddress('192.168.1.0/24')")
    @PostMapping("/admin/users")
    public User createUser(@RequestBody UserDTO dto) {
        return userService.create(dto);
    }
    
    // 基于权限的细粒度控制
    @PreAuthorize("hasAuthority('user:write') or (hasAuthority('user:read') and #id == authentication.principal.id)")
    @GetMapping("/users/{id}")
    public User getUser(@PathVariable Long id, 
                       @AuthenticationPrincipal UserDetails currentUser) {
        return userService.findById(id);
    }
    
    // 方法执行后验证:只能查看自己的订单详情
    @PostAuthorize("returnObject.userId == authentication.principal.id or hasRole('ADMIN')")
    @GetMapping("/orders/{orderId}")
    public Order getOrder(@PathVariable Long orderId) {
        return orderService.findById(orderId);
    }
    
    // 过滤返回结果:只能看到同部门的数据
    @PostFilter("filterObject.departmentId == authentication.principal.departmentId")
    @GetMapping("/employees")
    public List<Employee> listEmployees() {
        return employeeService.findAll();
    }
    
    // JSR-250注解
    @Secured({"ROLE_ADMIN", "ROLE_MANAGER"})
    @DeleteMapping("/admin/users/{id}")
    public void deleteUser(@PathVariable Long id) {
        userService.delete(id);
    }
}

九、测试相关注解

注解 作用 使用位置
@SpringBootTest 集成测试,加载完整应用上下文
@WebMvcTest 测试Web层,仅加载Controller相关组件
@DataJpaTest 测试数据访问层,仅加载JPA组件
@MockBean 创建Mock对象替换Spring容器中的Bean 字段
@SpyBean 创建Spy对象包装真实Bean 字段
@AutoConfigureMockMvc 自动配置MockMvc
@TestPropertySource 指定测试配置文件
@ActiveProfiles 激活特定Profile
@Sql 测试前执行SQL脚本 方法、类
@DirtiesContext 测试后清理Spring上下文 类、方法
@Timed 限制方法执行时间 方法
@RepeatedTest 重复执行测试 方法
@ParameterizedTest 参数化测试 方法

示例:

@SpringBootTest
@AutoConfigureMockMvc
@ActiveProfiles("test")
@TestPropertySource(locations = "classpath:application-test.properties")
public class UserControllerIntegrationTest {
    
    @Autowired
    private MockMvc mockMvc;
    
    @Autowired
    private ObjectMapper objectMapper;
    
    @MockBean
    private EmailService emailService;  // Mock外部服务
    
    @Test
    @Sql(scripts = "/test-data.sql")  // 测试前插入数据
    @DirtiesContext  // 测试后清理上下文
    public void testCreateUser() throws Exception {
        UserDTO dto = new UserDTO("test", "test@example.com");
        
        mockMvc.perform(post("/api/users")
                .contentType(MediaType.APPLICATION_JSON)
                .content(objectMapper.writeValueAsString(dto)))
            .andExpect(status().isCreated())
            .andExpect(jsonPath("$.username").value("test"));
        
        // 验证Mock对象被调用
        verify(emailService).sendWelcomeEmail(anyString());
    }
}

// Web层单元测试
@WebMvcTest(UserController.class)
public class UserControllerUnitTest {
    
    @Autowired
    private MockMvc mockMvc;
    
    @MockBean
    private UserService userService;
    
    @Test
    public void testGetUser() throws Exception {
        when(userService.findById(1L)).thenReturn(new User("test"));
        
        mockMvc.perform(get("/api/users/1"))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.username").value("test"));
    }
}

// JPA测试
@DataJpaTest
public class UserRepositoryTest {
    
    @Autowired
    private TestEntityManager entityManager;
    
    @Autowired
    private UserRepository userRepository;
    
    @Test
    public void testFindByEmail() {
        User user = new User("test", "test@example.com");
        entityManager.persist(user);
        
        Optional<User> found = userRepository.findByEmail("test@example.com");
        assertThat(found).isPresent();
    }
}

十、异步与定时任务注解

注解 作用 使用位置
@EnableAsync 启用异步方法支持 配置类
@Async 标记方法异步执行 方法
@EnableScheduling 启用定时任务 配置类
@Scheduled 标记定时任务方法 方法
@Scheduled(fixedRate) 固定频率执行 方法
@Scheduled(fixedDelay) 固定延迟执行 方法
@Scheduled(cron) Cron表达式执行 方法

示例:

@Configuration
@EnableAsync
@EnableScheduling
public class AsyncConfig implements AsyncConfigurer {
    
    @Override
    @Bean(name = "taskExecutor")
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(100);
        executor.setThreadNamePrefix("async-");
        executor.initialize();
        return executor;
    }
}

@Service
public class NotificationService {
    
    // 异步发送邮件,使用默认线程池
    @Async
    public void sendEmailAsync(String to, String subject, String content) {
        // 异步执行
        emailClient.send(to, subject, content);
    }
    
    // 使用指定线程池
    @Async("taskExecutor")
    public CompletableFuture<List<Notification>> fetchNotifications(Long userId) {
        List<Notification> notifications = notificationRepository.findByUserId(userId);
        return CompletableFuture.completedFuture(notifications);
    }
}

@Component
public class ScheduledTasks {
    
    // 每5秒执行一次
    @Scheduled(fixedRate = 5000)
    public void reportCurrentTime() {
        System.out.println("当前时间: " + LocalDateTime.now());
    }
    
    // 上次执行完成后延迟2秒再执行
    @Scheduled(fixedDelay = 2000)
    public void processQueue() {
        // 处理队列任务
    }
    
    // 每天凌晨2点执行
    @Scheduled(cron = "0 0 2 * * ?")
    public void dailyCleanup() {
        // 清理过期数据
    }
    
    // 工作日每30分钟执行
    @Scheduled(cron = "0 */30 * * * MON-FRI")
    public void businessHoursTask() {
        // 工作时间任务
    }
}

十一、Swagger/OpenAPI 注解(API文档)

注解 作用 使用位置
@Tag API分组标签
@Operation 接口描述 方法
@ApiResponse 响应描述 方法
@ApiResponses 多个响应描述 方法
@Parameter 参数描述 参数
@Schema 模型属性描述 类、字段
@Hidden 隐藏接口或字段 类、方法、字段

示例:

@Tag(name = "用户管理", description = "用户相关操作接口")
@RestController
@RequestMapping("/api/users")
public class UserController {
    
    @Operation(
        summary = "创建用户",
        description = "根据DTO创建新用户,返回创建后的用户信息",
        responses = {
            @ApiResponse(responseCode = "201", description = "创建成功"),
            @ApiResponse(responseCode = "400", description = "参数校验失败"),
            @ApiResponse(responseCode = "409", description = "用户名已存在")
        }
    )
    @PostMapping
    public ResponseEntity<User> createUser(
            @Valid 
            @RequestBody 
            @Parameter(description = "用户信息", required = true) 
            UserDTO userDTO) {
        // 实现
    }
    
    @Operation(summary = "根据ID查询用户")
    @GetMapping("/{id}")
    public User getUser(
            @Parameter(description = "用户ID", example = "123") 
            @PathVariable Long id) {
        return userService.findById(id);
    }
}

@Schema(description = "用户数据传输对象")
public class UserDTO {
    
    @Schema(description = "用户名", required = true, example = "zhangsan", minLength = 3, maxLength = 20)
    @NotBlank
    private String username;
    
    @Schema(description = "邮箱", required = true, example = "zhangsan@example.com")
    @Email
    private String email;
    
    @Schema(description = "年龄", minimum = "18", maximum = "120")
    @Min(18)
    private Integer age;
}

十二、Lombok 注解(代码生成)

注解 作用 使用位置
@Getter 生成getter方法 类、字段
@Setter 生成setter方法 类、字段
@ToString 生成toString方法
@EqualsAndHashCode 生成equals和hashCode方法
@NoArgsConstructor 生成无参构造器
@AllArgsConstructor 生成全参构造器
@RequiredArgsConstructor 生成必需参数构造器(final字段)
@Data 组合注解(@Getter + @Setter + @ToString + @EqualsAndHashCode + @RequiredArgsConstructor)
@Builder 生成建造者模式代码
@Slf4j 生成SLF4J日志对象
@Log4j2 生成Log4j2日志对象
@Value 生成不可变对象(final类 + 全final字段 + 全参数构造器 + getter)
@SneakyThrows 悄悄抛出受检异常 方法

示例:

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "users")
public class User {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(nullable = false)
    private String username;
    
    @Column(nullable = false)
    private String email;
    
    @Builder.Default  // 设置默认值
    private LocalDateTime createdTime = LocalDateTime.now();
    
    @ToString.Exclude  // toString中排除
    @EqualsAndHashCode.Exclude  // equals和hashCode中排除
    private String password;
}

// 使用Builder
User user = User.builder()
    .username("zhangsan")
    .email("zhangsan@example.com")
    .build();

@Slf4j
@Service
public class OrderService {
    
    public void processOrder(Order order) {
        log.info("Processing order: {}", order.getId());
        // 业务逻辑
        log.debug("Order details: {}", order);
    }
    
    @SneakyThrows(InterruptedException.class)  // 无需显式try-catch
    public void asyncProcess() {
        Thread.sleep(1000);
    }
}

十三、Jackson JSON 处理注解

注解 作用 使用位置
@JsonProperty 指定JSON属性名 字段、方法
@JsonIgnore 忽略字段序列化 字段、方法
@JsonIgnoreProperties 忽略多个属性
@JsonFormat 指定日期/数字格式 字段
@JsonInclude 指定包含策略(NON_NULL/NON_EMPTY等) 类、字段
@JsonSerialize 指定自定义序列化器 字段
@JsonDeserialize 指定自定义反序列化器 字段
@JsonView 指定视图序列化 类、字段、方法

示例:

@JsonInclude(JsonInclude.Include.NON_NULL)  // 忽略null字段
public class UserDTO {
    
    @JsonProperty("user_id")  // JSON中显示为user_id
    private Long id;
    
    @JsonIgnore  // 不序列化到JSON
    private String password;
    
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime createdTime;
    
    @JsonSerialize(using = MoneySerializer.class)
    @JsonDeserialize(using = MoneyDeserializer.class)
    private BigDecimal balance;
    
    @JsonView(Views.Public.class)  // 只在Public视图显示
    private String username;
    
    @JsonView(Views.Internal.class)  // 只在Internal视图显示
    private String phone;
}

// 使用
public class Views {
    public static class Public {}
    public static class Internal extends Public {}
}

@JsonView(Views.Public.class)
@GetMapping("/users/{id}")
public User getUserPublic(@PathVariable Long id) { ... }

@JsonView(Views.Internal.class)
@GetMapping("/admin/users/{id}")
public User getUserInternal(@PathVariable Long id) { ... }
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐