Spring & Spring Boot 常用注解整理
- 先理解核心概念:什么是注解(Annotation)?
- 第一部分:IOC(控制反轉)和 DI(依賴注入)
- 1. @Component
- 2. @Service, @Repository, @Controller
- 3. @Autowired
- 4. @Qualifier
- 第二部分:Spring MVC(處理 HTTP 請求)
- 1. @RestController vs @Controller
- 2. @GetMapping / @PostMapping
- 3. @PathVariable 和 @RequestParam
- 第三部分:配置相關注解
- 1. @Configuration 和 @Bean
- 2. @Value
- 第四部分:Spring Boot 核心注解
- @SpringBootApplication
- 第五部分:數據庫和事務
- 1. @Entity 和 @Id
- 2. @Transactional
- 第六部分:AOP(面向切面編程)
- 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:“這個類交給你管理,我需要的時候找你要實例”。
代碼示例:
@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 請求)。
代碼對比:
@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(類似找人借東西,不用自己造)。
代碼示例:
@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 的名字。
代碼示例:
// 定義兩個數據源
@Component("mysqlDataSource")
public class MySQLDataSource implements DataSource { ... }@Component("postgresDataSource")
public class PostgresDataSource implements DataSource { ... }// 使用時指定名稱
@Service
public class DataService {@Autowired@Qualifier("mysqlDataSource") // 明確告訴 Spring 注入名為 "mysqlDataSource" 的 Beanprivate 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
)。
代碼對比:
// 傳統 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)
。
代碼示例:
@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
)。
代碼示例:
@GetMapping("/users/{id}") // URL 模板:{id} 是占位符
public User getUserById(@PathVariable Long id) { // 獲取路徑中的 idreturn userService.findById(id);
}@GetMapping("/search")
public List<User> searchUsers(@RequestParam String keyword) { // 獲取參數 ?keyword=xxxreturn 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。
代碼示例:
@Configuration // 告訴 Spring:“這是一個配置類”
public class AppConfig {@Bean // 這個方法返回的對象會被 Spring 管理public DataSource dataSource() {return new HikariDataSource(); // 手動創建一個數據源}
}
2. @Value
作用:從配置文件(如 application.properties
)中讀取值。
示例:
# application.properties
app.name=My Awesome App
database.url=jdbc:mysql://localhost:3306/mydb
@Component
public class AppConfig {@Value("${app.name}") // 注入 app.name 的值private String appName;@Value("${database.url}") // 注入數據庫 URLprivate 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
等)。
代碼示例:
@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 實體類(對應數據庫表)和主鍵字段。
代碼示例:
@Entity // 告訴 Spring:“這是一個數據庫表對應的實體類”
public class User {@Id // 標記為主鍵private Long id;private String name;// 省略 getter/setter
}
2. @Transactional
作用:聲明事務,確保方法內的數據庫操作要么全部成功,要么全部回滾。
代碼示例:
@Service
public class OrderService {@Autowiredprivate 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
代碼示例:
@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:“這個方法要保證事務!” |