当前位置: 首页 > news >正文

Spring / Spring Boot 常用注解

核心原则(先看这段)

  • 把行为(业务)放在 Service 层,事务/缓存/异步等注解一般放在 Service 层,不要把复杂逻辑放到 Controller。

  • 首选构造器注入(constructor injection),比字段注入更利于测试与不可变性。

  • 注解很多都是“语义化的标记 + 框架在运行时的处理”,理解背后的代理/生命周期很重要(例如 @Transactional 基于 AOP 代理,自调用不会触发代理逻辑)。

核心/启动与配置注解

@SpringBootApplication // 等价于 @Configuration + @EnableAutoConfiguration + @ComponentScan(默认扫描启动类包及子包)
public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}
}

  • @Configuration:Java 配置类(替代 XML)。

  • @Bean:方法级别把返回对象注册为 Spring Bean(可设置 init/destroy)。

  • @ComponentScan:定制扫描包路径(启动类包位置很关键,建议把主类放在根包)。

  • @EnableConfigurationProperties:启用 @ConfigurationProperties 绑定(在 Spring Boot 中,直接将 @ConfigurationProperties 标注成 @Component 也可被扫描到)。

  • @ConfigurationProperties(prefix="..."):批量强类型注入配置(推荐用于复杂/层级配置,支持校验 @Validated)。

示例(YAML + 配置类):

# application.yml
app:name: demotimeout: 30nested:enabled: true
@Component
@ConfigurationProperties(prefix = "app")
@Validated
public class AppProperties {@NotBlankprivate String name;private int timeout;private Nested nested = new Nested();// getters/setterspublic static class Nested { private boolean enabled; /* getter/setter */ }
}

组件(stereotype)注解与区别

  • @Component:通用组件(任何层通用)。

  • @Service:业务层语义化(仅为语义,便于识别)。

  • @Repository:持久层语义化,且启用 异常翻译(把 JPA/Hibernate 的异常翻译为 Spring 的 DataAccessException)。

  • @Controller:MVC 控制器,通常返回视图(与 @ResponseBody 组合可返回 JSON)。

  • @RestController:@Controller + @ResponseBody,更常用于 REST API。

何时用?按层次用对应注解(可读性和工具/监控的好处)。

依赖注入 / Bean 选择 / Scope / 生命周期

  • 注入方式对比(推荐):

    • 构造器注入(推荐):支持 final,利于单元测试。

    • Setter 注入:有状态或可选依赖时可用。

    • 字段注入(@Autowired 在字段上):不推荐(难测、不可 final)。

@Service
public class MyService {private final UserRepository repo;public MyService(UserRepository repo) { this.repo = repo; } // 自动注入(Spring 4.3+)
}

  • @Autowired(按类型注入),@Qualifier("name") 或 @Primary(用于同类型多个 Bean);

  • @Resource(JSR-250,按名称优先);

  • @Value("${xxx}")(注入单个配置值);

  • @ConfigurationProperties(批量注入复杂配置);

Bean scope:

  • @Scope("singleton")(默认)

  • @Scope("prototype")(每次请求新实例)

  • 还有 request、session(web 场景)等

生命周期:

  • @PostConstruct、@PreDestroy(JSR)

  • 或在 @Bean(initMethod="...", destroyMethod="...") 指定

  • InitializingBean / DisposableBean(接口)

    示例:

@PostConstruct
public void init(){ /* init work */ }
@PreDestroy
public void cleanup(){ /* release */ }

Web / Controller 相关注解(常用)

  • 路由映射:@RequestMapping、@GetMapping、@PostMapping、@PutMapping、@DeleteMapping。

  • 参数绑定:@PathVariable、@RequestParam、@RequestBody、@RequestHeader、@CookieValue。

  • 返回:@ResponseBody(将返回对象序列化为 JSON) → @RestController 更常用。

  • 状态码:@ResponseStatus(HttpStatus.CREATED)。

  • 验证:@Valid(与 Bean Validation 联动) + DTO 上加注解 @NotNull/@Size...。

  • 异常处理:@ControllerAdvice + @ExceptionHandler(全局异常/统一返回)或 @RestControllerAdvice。

示例:

@RestController
@RequestMapping("/users")
public class UserController {@PostMapping@ResponseStatus(HttpStatus.CREATED)public UserDto create(@Valid @RequestBody CreateUserDto dto) { ... }
}

数据访问与事务(重要)

  • @Repository(DAO层) + JPA @Entity / MyBatis 接口等。

  • @Transactional(关键点):

    • 放在 Service 层方法上最合适(控制事务边界)。

    • 常用属性:propagation、isolation、readOnly、rollbackFor。

    • 注意:@Transactional 基于代理(AOP),内部自调用不会触发事务(self-invocation)

@Service
public class OrderService {@Transactional(rollbackFor = Exception.class)public void placeOrder(OrderDto dto){ ... }
}

常见坑:

  • 在同一个类里面 public methodA() 调 private methodB() 并给 methodB 标注 @Transactional,事务不会生效(因为代理不会拦截内部调用)。解决:把方法拆到另一个 Bean,或使用 AopContext.currentProxy() (不常用)。

AOP(切面)相关注解

  • @Aspect(切面类) + @Before / @After / @AfterReturning / @Around / @Pointcut。

  • 典型用途:日志、监控、权限校验、限流、重试等。

@Aspect
@Component
public class LoggingAspect {@Pointcut("execution(* com.example.service..*(..))")public void serviceMethods() {}@Around("serviceMethods()")public Object log(ProceedingJoinPoint pjp) throws Throwable {long t = System.currentTimeMillis();Object ret = pjp.proceed();System.out.println("took " + (System.currentTimeMillis() - t));return ret;}
}

异步 / 调度 / 缓存 / 安全(常见功能注解)

  • 异步:@EnableAsync(配置类) + @Async(方法) → 返回 void / Future / CompletableFuture。注意自调用失效

  • 调度:@EnableScheduling + @Scheduled(cron = "...")。

  • 缓存:@EnableCaching + @Cacheable / @CacheEvict / @CachePut。

  • 方法级安全:@PreAuthorize("hasRole('ADMIN')") / @Secured,配合 @EnableMethodSecurity(或旧版 @EnableGlobalMethodSecurity)。

示例(异步):

@Configuration
@EnableAsync
public class AsyncConfig {}
@Service
public class MailService {@Asyncpublic CompletableFuture<Void> sendAsync(...) { ... }
}

条件化 & 自动配置注解(Spring Boot 自动化)

  • @ConditionalOnProperty(name="...", havingValue="..."):基于配置决定是否装配某 Bean。

  • @ConditionalOnClass:当类在 classpath 上时才生效(常用在 starter/自动配置中)。

  • @ConditionalOnMissingBean:容器中没有指定类型的 Bean 时才创建默认 bean。

  • @Profile("dev"):按 profile 加载(spring.profiles.active=dev)。

示例(有默认实现但允许覆盖):

@Configuration
@ConditionalOnClass(SomeClient.class)
public class AutoConfig {@Bean@ConditionalOnMissingBeanpublic MyClient myClient(){ return new DefaultMyClient(); }
}

测试相关注解(常见)

  • @SpringBootTest:集成测试,启动整个上下文(慢)。

  • @WebMvcTest(controllers = ...):只加载 Web 层(适合 Controller 测试)。

  • @DataJpaTest:只加载 JPA 相关组件(内存数据库)。

  • @MockBean:在 Spring 容器中替换某个 Bean 为 mock。

  • @TestConfiguration:测试专用配置类。

常见坑、注意事项与最佳实践(实战派)

  1. 优先构造器注入(可用 final,更安全)。

  2. @Transactional 放在 public 方法上且不要依赖自调用来触发事务。

  3. Controller 层只做参数校验/返回,不做事务处理和复杂业务(业务放 Service)。

  4. 使用 @ConfigurationProperties 管理复杂配置,@Value 仅用于单值注入。

  5. @Repository 会做异常翻译(推荐持久层使用)。

  6. @RestControllerAdvice + @ExceptionHandler 做统一异常处理和统一响应结构。

  7. 生产环境建议对定时任务、异步线程池、缓存策略做合理配置与监控。

  8. 用 @Profile 管理 dev/test/prod 配置差异。

  9. 注意 @Async / @Transactional/@Cacheable 等基于代理的注解,均受自调用影响。

速查小表(快速记忆)

  • 启动:@SpringBootApplication

  • 配置:@Configuration / @Bean / @ConfigurationProperties

  • 组件:@Component / @Service / @Repository / @Controller / @RestController

  • 注入:@Autowired / @Qualifier / @Value / 构造器注入

  • Web:@GetMapping / @PostMapping / @RequestBody / @PathVariable

  • 事务:@Transactional(放 Service)

  • AOP:@Aspect / @Around / @Pointcut

  • 异步:@EnableAsync + @Async

  • 调度:@EnableScheduling + @Scheduled

  • 缓存:@EnableCaching + @Cacheable

  • 条件/自动配置:@ConditionalOnProperty / @ConditionalOnClass / @ConditionalOnMissingBean

  • 测试:@SpringBootTest / @WebMvcTest / @MockBean

代码示例:Controller → Service → Repository + 配置属性(可拷贝运行)

// Application.java
@SpringBootApplication
public class App {public static void main(String[] args) {SpringApplication.run(App.class, args);}
}// AppProperties.java
@Component
@ConfigurationProperties(prefix = "app")
@Validated
public class AppProperties {@NotBlank private String name;private int timeout;// getters/setters
}// UserEntity.java
@Entity
@Table(name = "users")
public class User {@Id @GeneratedValue private Long id;private String username;// getters/setters
}// UserRepository.java (Spring Data JPA example)
@Repository
public interface UserRepository extends JpaRepository<User, Long> {}// UserService.java
@Service
public class UserService {private final UserRepository userRepository;public UserService(UserRepository userRepository) { this.userRepository = userRepository; }@Transactionalpublic User createUser(String username) {User u = new User(); u.setUsername(username);return userRepository.save(u);}@Transactional(readOnly = true)public User getUser(Long id){ return userRepository.findById(id).orElse(null); }
}// UserController.java
@RestController
@RequestMapping("/users")
public class UserController {private final UserService userService;private final AppProperties props;public UserController(UserService userService, AppProperties props){this.userService = userService; this.props = props;}@PostMappingpublic ResponseEntity<User> create(@RequestParam String name){User u = userService.createUser(name);return ResponseEntity.status(HttpStatus.CREATED).body(u);}@GetMapping("/{id}")public ResponseEntity<User> get(@PathVariable Long id){return ResponseEntity.of(Optional.ofNullable(userService.getUser(id)));}
}
http://www.dtcms.com/a/399250.html

相关文章:

  • 【SQL中Lag()和LEAD()的用法】
  • 怎么做代理人金沙网站网页界面设计与分析
  • java中设计思想和架构理念
  • 比PostMan更简洁易用,一款国产开源免费的接口管理工具 - PostIn
  • 什么网站管理系统好网络工程师自学难吗
  • JavaEE 初阶第二十四期:网络原理,底层框架的“通关密码”(四)
  • conda安装软件包的通道conda-forge
  • 【数据库】sql基本语句
  • 手机网站应该怎么做建设网站那个公司好
  • linux 常用命令(包含:网络工具、进程管理工具、常用的)
  • Android
  • 产品设计前硬件考虑的事/示波器/EMC/EMI/热敏电阻
  • UE5GAS GameAbility源码解析 CommitAbility
  • 深圳 网站设计公司排名南通建筑人才网
  • 基于C#实现TCP/UDP通信及文件传输
  • Product Hunt 每日热榜 | 2025-09-23
  • 未来信息综合技术
  • 自己做网站卖什么网站建设侵权行为有哪些
  • 《笑傲江湖Ⅱ:东方不败》的Python实现
  • Redission3.11能连接Redis6+的吗,怎么连接
  • 【C语言代码】数组排序
  • 网站自动识别手机辣条网站建设书
  • 做信息图的网站有哪些深圳企业建站平台
  • 【AI论文】潜在区域划分网络:生成建模、表征学习与分类的统一原理
  • 网站 建设ppt网络舆情的应对及处理
  • Qwen又把Qwen-Image-Edit升级了!
  • 楼盘网站开发报价企业服务平台网站建设
  • 网站建设有利于关于绿色环保网站的建设历程
  • 【Linux】基础指令和基础知识点
  • 阅读的网站建设需要多少钱中小企业网站建设流程