Spring & Spring Boot 常用注解整理
-
-
- 先理解核心概念:什么是注解(Annotation)?
- [第一部分:IOC(控制反转)和 DI(依赖注入)](#第一部分:IOC(控制反转)和 DI(依赖注入))
-
- [1. @Component](#1. @Component)
- [2. @Service, @Repository, @Controller](#2. @Service, @Repository, @Controller)
- [3. @Autowired](#3. @Autowired)
- [4. @Qualifier](#4. @Qualifier)
- [第二部分:Spring MVC(处理 HTTP 请求)](#第二部分:Spring MVC(处理 HTTP 请求))
-
- [1. @RestController vs @Controller](#1. @RestController vs @Controller)
- [2. @GetMapping / @PostMapping](#2. @GetMapping / @PostMapping)
- [3. @PathVariable 和 @RequestParam](#3. @PathVariable 和 @RequestParam)
- 第三部分:配置相关注解
-
- [1. @Configuration 和 @Bean](#1. @Configuration 和 @Bean)
- [2. @Value](#2. @Value)
- [第四部分:Spring Boot 核心注解](#第四部分:Spring Boot 核心注解)
- 第五部分:数据库和事务
-
- [1. @Entity 和 @Id](#1. @Entity 和 @Id)
- [2. @Transactional](#2. @Transactional)
- 第六部分:AOP(面向切面编程)
-
- [1. @Aspect 和 @Before](#1. @Aspect 和 @Before)
- 总结:注解的核心作用
-
先理解核心概念:什么是注解(Annotation)?
类比 :注解就像代码里的"便利贴",用来告诉 Spring 框架:"这个类/方法/变量有什么特殊用途"。
作用:简化配置,让框架自动帮你处理一些事情(比如创建对象、管理依赖、处理请求等)。
第一部分:IOC(控制反转)和 DI(依赖注入)
核心思想 :把对象的创建和管理交给 Spring 容器,而不是自己手动 new
对象。
注解 | 说明 | 示例 |
---|---|---|
@Component |
通用组件标记,被扫描的类会纳入 Spring 容器管理 | @Component public class MyComponent { ... } |
@Service |
标记服务层组件,属于@Component 的特化形式 |
@Service public class UserService { ... } |
@Repository |
标记数据访问层组件(DAO层),具有数据库异常转译功能 | @Repository public class UserDao { ... } |
@Controller |
标记控制器组件(Web层) | @Controller public class UserController { ... } |
@Autowired |
自动注入依赖,默认按类型匹配 | @Autowired private UserService userService; |
@Qualifier |
按名称指定注入的 Bean | @Autowired @Qualifier("userServiceImplA") private UserService service; |
@Primary |
标记首选的 Bean(存在多个同类型 Bean 时优先注入) | @Bean @Primary public DataSource primaryDataSource() { ... } |
@Scope |
定义 Bean 的作用域(singleton/prototype等) | @Component @Scope("prototype") public class MyPrototypeBean { ... } |
1. @Component
作用 :告诉 Spring:"这个类交给你管理,我需要的时候找你要实例"。
代码示例:
java
@Component // 贴上这个标签,Spring 就会自动创建 MyComponent 的实例(Bean)
public class MyComponent {
public void hello() {
System.out.println("Hello from MyComponent!");
}
}
使用场景:通用的工具类、第三方库的适配类等。
2. @Service, @Repository, @Controller
本质 :它们都是 @Component
的"马甲",用途相同,只是名字不同,为了代码可读性。
@Service
:标记业务逻辑层(如处理用户注册、订单支付)。@Repository
:标记数据访问层(如操作数据库)。@Controller
:标记 Web 控制器(处理 HTTP 请求)。
代码对比:
java
@Service
public class UserService { // 业务逻辑层
public void registerUser(String name) { ... }
}
@Repository
public class UserDao { // 数据访问层
public User findUserById(Long id) { ... }
}
@Controller
public class UserController { // 处理 HTTP 请求
@GetMapping("/users")
public String listUsers() { ... }
}
3. @Autowired
作用 :让 Spring 自动帮你"注入"依赖的 Bean(类似找人借东西,不用自己造)。
代码示例:
java
@Service
public class UserService {
@Autowired // Spring 会自动找一个 UserDao 的 Bean 注入到这里
private UserDao userDao;
public User findUser(Long id) {
return userDao.findUserById(id); // 直接使用 userDao,不需要 new UserDao()
}
}
原理 :Spring 会在容器中查找匹配类型的 Bean,自动赋值给 userDao
。
4. @Qualifier
问题场景 :如果有多个同类型的 Bean,Spring 不知道注入哪一个。
解决 :用 @Qualifier
指定 Bean 的名字。
代码示例:
java
// 定义两个数据源
@Component("mysqlDataSource")
public class MySQLDataSource implements DataSource { ... }
@Component("postgresDataSource")
public class PostgresDataSource implements DataSource { ... }
// 使用时指定名称
@Service
public class DataService {
@Autowired
@Qualifier("mysqlDataSource") // 明确告诉 Spring 注入名为 "mysqlDataSource" 的 Bean
private DataSource dataSource;
}
第二部分:Spring MVC(处理 HTTP 请求)
注解 | 说明 | 示例 |
---|---|---|
@RestController |
组合注解(@Controller + @ResponseBody ),用于 REST API |
@RestController public class ApiController { ... } |
@RequestMapping |
映射 HTTP 请求路径,可指定 method | @RequestMapping(value="/users", method=RequestMethod.GET) |
@GetMapping |
简化 GET 请求映射(同理有@PostMapping 、@PutMapping 等) |
@GetMapping("/{id}") public User getUser(@PathVariable Long id) |
@PathVariable |
绑定 URL 路径中的变量 | @GetMapping("/users/{id}") public User getById(@PathVariable Long id) |
@RequestParam |
绑定请求参数(支持默认值、是否必传等) | @GetMapping("/search") public List<User> search(@RequestParam(defaultValue = "") String keyword) |
@RequestBody |
将请求体内容反序列化为 Java 对象(如 JSON) | @PostMapping public User create(@RequestBody User user) { ... } |
@ResponseBody |
将方法返回值序列化为响应体(如 JSON) | 已内置在@RestController 中 |
@ExceptionHandler |
处理控制器内的特定异常 | @ExceptionHandler(UserNotFoundException.class) public ResponseEntity<String> handleException() { ... } |
@CrossOrigin |
允许跨域请求 | @CrossOrigin(origins = "http://example.com") |
1. @RestController vs @Controller
@Controller
:传统 MVC 控制器,返回视图(如 JSP 页面)。@RestController
:专门用于 REST API,直接返回 JSON 数据(内部包含@ResponseBody
)。
代码对比:
java
// 传统 Controller(返回视图名,由模板引擎渲染)
@Controller
public class OldController {
@GetMapping("/hello")
public String hello() {
return "hello-page"; // 对应 src/main/resources/templates/hello-page.html
}
}
// REST Controller(返回 JSON)
@RestController
public class ApiController {
@GetMapping("/user")
public User getUser() {
return new User(1, "Alice"); // 自动转换为 JSON:{ "id": 1, "name": "Alice" }
}
}
2. @GetMapping / @PostMapping
作用 :简化 HTTP 请求映射,替代 @RequestMapping(method=RequestMethod.GET)
。
代码示例:
java
@RestController
public class UserController {
// 处理 GET 请求:http://localhost:8080/users
@GetMapping("/users")
public List<User> listUsers() {
return userService.getAllUsers();
}
// 处理 POST 请求:http://localhost:8080/users
@PostMapping("/users")
public User createUser(@RequestBody User user) { // @RequestBody 表示接收 JSON 数据
return userService.saveUser(user);
}
}
3. @PathVariable 和 @RequestParam
@PathVariable
:从 URL 路径中获取变量(如/users/123
中的123
)。@RequestParam
:从 URL 参数中获取值(如/search?keyword=java
中的keyword
)。
代码示例:
java
@GetMapping("/users/{id}") // URL 模板:{id} 是占位符
public User getUserById(@PathVariable Long id) { // 获取路径中的 id
return userService.findById(id);
}
@GetMapping("/search")
public List<User> searchUsers(@RequestParam String keyword) { // 获取参数 ?keyword=xxx
return userService.search(keyword);
}
第三部分:配置相关注解
注解 | 说明 | 示例 |
---|---|---|
@Configuration |
标记类为配置类(替代 XML 配置文件) | @Configuration public class AppConfig { ... } |
@Bean |
声明方法返回的对象作为 Bean 加入容器 | @Bean public DataSource dataSource() { return new HikariDataSource(); } |
@Value |
注入配置文件中的值 | @Value("${db.url}") private String dbUrl; |
@PropertySource |
加载指定 properties 文件 | @Configuration @PropertySource("classpath:custom.properties") |
@ConfigurationProperties |
批量绑定配置文件属性到对象(需配合@EnableConfigurationProperties ) |
@Component @ConfigurationProperties(prefix="app") public class AppConfig { private String name; ... } |
@Profile |
指定 Bean 生效的环境 | @Bean @Profile("dev") public DataSource devDataSource() { ... } |
1. @Configuration 和 @Bean
作用:替代 XML 配置文件,手动定义 Bean。
代码示例:
java
@Configuration // 告诉 Spring:"这是一个配置类"
public class AppConfig {
@Bean // 这个方法返回的对象会被 Spring 管理
public DataSource dataSource() {
return new HikariDataSource(); // 手动创建一个数据源
}
}
2. @Value
作用 :从配置文件(如 application.properties
)中读取值。
示例:
properties
# application.properties
app.name=My Awesome App
database.url=jdbc:mysql://localhost:3306/mydb
java
@Component
public class AppConfig {
@Value("${app.name}") // 注入 app.name 的值
private String appName;
@Value("${database.url}") // 注入数据库 URL
private String dbUrl;
}
第四部分:Spring Boot 核心注解
注解 | 说明 | 示例 |
---|---|---|
@SpringBootApplication |
启动类注解 (包含@Configuration +@EnableAutoConfiguration +@ComponentScan ) |
@SpringBootApplication public class MyApp { public static void main(String[] args) { SpringApplication.run(MyApp.class, args); } } |
@EnableAutoConfiguration |
启用自动配置机制(通常已包含在@SpringBootApplication 中) |
显式使用:@SpringBootApplication @EnableAutoConfiguration |
@ConditionalOnProperty |
根据配置属性条件化创建 Bean | @Bean @ConditionalOnProperty(name="feature.enabled", havingValue="true") public FeatureBean featureBean() { ... } |
@SpringBootApplication
作用:标记启动类,包含三个核心功能:
@Configuration
:这是一个配置类。@EnableAutoConfiguration
:开启自动配置(如自动配置数据库连接池)。@ComponentScan
:自动扫描当前包及子包下的组件(@Component
,@Service
等)。
代码示例:
java
@SpringBootApplication // 一切从这里开始
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args); // 启动 Spring Boot 应用
}
}
第五部分:数据库和事务
注解 | 说明 | 示例 |
---|---|---|
@Transactional |
声明事务管理(可加在类或方法上) | @Transactional public void updateUser(User user) { ... } |
@Entity |
JPA 实体类标记 | @Entity public class User { @Id private Long id; ... } |
@JpaRepository |
Spring Data JPA 的仓库接口 | public interface UserRepository extends JpaRepository<User, Long> { ... } |
1. @Entity 和 @Id
作用:标记 JPA 实体类(对应数据库表)和主键字段。
代码示例:
java
@Entity // 告诉 Spring:"这是一个数据库表对应的实体类"
public class User {
@Id // 标记为主键
private Long id;
private String name;
// 省略 getter/setter
}
2. @Transactional
作用:声明事务,确保方法内的数据库操作要么全部成功,要么全部回滚。
代码示例:
java
@Service
public class OrderService {
@Autowired
private OrderRepository orderRepository;
@Transactional // 开启事务
public void placeOrder(Order order) {
orderRepository.save(order); // 保存订单
// 如果这里抛出异常(如库存不足),整个事务会回滚,订单不会被保存
}
}
第六部分:AOP(面向切面编程)
核心思想:在不修改原有代码的情况下,统一处理日志、权限、事务等横切关注点。
注解 | 说明 | 示例 |
---|---|---|
@Aspect |
声明切面类 | @Aspect @Component public class LoggingAspect { ... } |
@Pointcut |
定义切入点表达式 | @Pointcut("execution(* com.example.service.*.*(..))") public void serviceMethods() {} |
@Before |
前置通知 | @Before("serviceMethods()") public void logBefore(JoinPoint jp) { ... } |
1. @Aspect 和 @Before
代码示例:
java
@Aspect // 告诉 Spring:"这是一个切面类"
@Component
public class LoggingAspect {
// 定义切入点:拦截所有 Service 层的方法
@Pointcut("execution(* com.example.service.*.*(..))")
public void serviceMethods() {}
// 前置通知:在方法执行前打印日志
@Before("serviceMethods()")
public void logBefore(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();
System.out.println("准备执行方法:" + methodName);
}
}
总结:注解的核心作用
场景 | 常用注解 | 类比解释 |
---|---|---|
管理对象 | @Component , @Service 等 |
告诉 Spring:"这个类归你管!" |
依赖注入 | @Autowired , @Qualifier |
告诉 Spring:"我需要这个,帮我拿!" |
处理 HTTP 请求 | @RestController , @GetMapping |
告诉 Spring:"这个方法是处理某个 URL 的!" |
读取配置 | @Value , @ConfigurationProperties |
告诉 Spring:"把配置文件的值给我!" |
事务管理 | @Transactional |
告诉 Spring:"这个方法要保证事务!" |
