文章目錄
- 前言
- 1. 核心啟動注解
- @SpringBootApplication
- @EnableAutoConfiguration
- @SpringBootConfiguration
- 2. 組件注解
- @Component及其衍生注解
- @Component
- @Service
- @Repository
- @Controller
- @RestController
- 3. 依賴注入注解
- @Autowired
- @Qualifier
- @Primary
- 4. Web相關注解
- 請求映射注解
- @RequestMapping
- HTTP方法特定注解
- 參數綁定注解
- @PathVariable
- @RequestParam
- @RequestBody
- @RequestHeader
- 5. 配置相關注解
- @Configuration
- @Bean
- @Value
- @ConfigurationProperties
- 6. 條件注解
- @Conditional系列
- 7. 測試注解
- @SpringBootTest
- @WebMvcTest
- @DataJpaTest
- 8. 事務注解
- @Transactional
- 9. 異步處理注解
- @Async
- 10. 緩存注解
- @Cacheable、@CacheEvict、@CachePut
- 11. 定時任務注解
- @Scheduled
- 12. 實際應用示例
- 實體類
- Repository層
- Service層
- Controller層
- 總結
- Spring Boot 注解對比表格
前言
Spring Boot通過大量的注解簡化了Java企業級應用的開發,讓開發者能夠以聲明式的方式配置應用程序。本文將系統性地介紹Spring Boot中最重要的注解,幫助開發者深入理解其原理和使用場景。
1. 核心啟動注解
@SpringBootApplication
這是Spring Boot最核心的注解,它是一個組合注解,包含了:
@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}
等價于以下三個注解的組合:
@SpringBootConfiguration
:標識這是一個配置類@EnableAutoConfiguration
:開啟自動配置@ComponentScan
:開啟組件掃描
@EnableAutoConfiguration
自動配置是Spring Boot的核心特性,它會根據類路徑下的依賴自動配置Bean:
@EnableAutoConfiguration
@ComponentScan
public class ManualConfiguration {// 手動配置類
}
@SpringBootConfiguration
繼承自@Configuration
,用于標識配置類:
@SpringBootConfiguration
public class AppConfig {@Beanpublic MyService myService() {return new MyServiceImpl();}
}
2. 組件注解
@Component及其衍生注解
@Component
最基礎的組件注解,標識一個Spring管理的組件:
@Component
public class DataProcessor {public void process(String data) {// 處理邏輯}
}
@Service
業務層組件,語義化更強:
@Service
public class UserService {public User findById(Long id) {// 業務邏輯return new User();}
}
@Repository
數據訪問層組件,提供異常轉換功能:
@Repository
public class UserRepository {@Autowiredprivate JdbcTemplate jdbcTemplate;public List<User> findAll() {return jdbcTemplate.query("SELECT * FROM users", (rs, rowNum) -> new User(rs.getLong("id"), rs.getString("name")));}
}
@Controller
控制器組件,處理HTTP請求:
@Controller
public class UserController {@GetMapping("/users")public String listUsers(Model model) {// 返回視圖名稱return "user-list";}
}
@RestController
RESTful控制器,結合了@Controller
和@ResponseBody
:
@RestController
@RequestMapping("/api/users")
public class UserRestController {@Autowiredprivate UserService userService;@GetMappingpublic List<User> getAllUsers() {return userService.findAll();}@PostMappingpublic User createUser(@RequestBody User user) {return userService.save(user);}
}
3. 依賴注入注解
@Autowired
自動裝配依賴:
@Service
public class OrderService {// 字段注入@Autowiredprivate UserService userService;// 構造函數注入(推薦)private final PaymentService paymentService;@Autowiredpublic OrderService(PaymentService paymentService) {this.paymentService = paymentService;}// Setter注入private EmailService emailService;@Autowiredpublic void setEmailService(EmailService emailService) {this.emailService = emailService;}
}
@Qualifier
當有多個同類型Bean時,指定具體注入哪個:
@Service
public class NotificationService {@Autowired@Qualifier("emailSender")private MessageSender emailSender;@Autowired@Qualifier("smsSender")private MessageSender smsSender;
}
@Primary
標識優先注入的Bean:
@Component
@Primary
public class DefaultMessageSender implements MessageSender {// 默認實現
}
4. Web相關注解
請求映射注解
@RequestMapping
通用請求映射:
@RestController
@RequestMapping("/api/products")
public class ProductController {@RequestMapping(value = "/{id}", method = RequestMethod.GET)public Product getProduct(@PathVariable Long id) {return productService.findById(id);}
}
HTTP方法特定注解
@RestController
@RequestMapping("/api/books")
public class BookController {@GetMappingpublic List<Book> getAllBooks() {return bookService.findAll();}@GetMapping("/{id}")public Book getBook(@PathVariable Long id) {return bookService.findById(id);}@PostMappingpublic Book createBook(@RequestBody Book book) {return bookService.save(book);}@PutMapping("/{id}")public Book updateBook(@PathVariable Long id, @RequestBody Book book) {book.setId(id);return bookService.update(book);}@DeleteMapping("/{id}")public void deleteBook(@PathVariable Long id) {bookService.delete(id);}
}
參數綁定注解
@PathVariable
綁定URL路徑參數:
@GetMapping("/users/{userId}/orders/{orderId}")
public Order getOrder(@PathVariable Long userId, @PathVariable Long orderId) {return orderService.findByUserAndId(userId, orderId);
}
@RequestParam
綁定請求參數:
@GetMapping("/search")
public List<Product> searchProducts(@RequestParam String keyword,@RequestParam(defaultValue = "0") int page,@RequestParam(defaultValue = "10") int size) {return productService.search(keyword, page, size);
}
@RequestBody
綁定請求體:
@PostMapping("/users")
public User createUser(@RequestBody User user) {return userService.create(user);
}
@RequestHeader
綁定請求頭:
@GetMapping("/profile")
public UserProfile getProfile(@RequestHeader("Authorization") String token) {return userService.getProfileByToken(token);
}
5. 配置相關注解
@Configuration
標識配置類:
@Configuration
public class DatabaseConfig {@Bean@Primarypublic DataSource primaryDataSource() {return DataSourceBuilder.create().url("jdbc:mysql://localhost:3306/primary").build();}@Beanpublic DataSource secondaryDataSource() {return DataSourceBuilder.create().url("jdbc:mysql://localhost:3306/secondary").build();}
}
@Bean
聲明Bean:
@Configuration
public class AppConfig {@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}@Bean@ConditionalOnProperty(name = "app.cache.enabled", havingValue = "true")public CacheManager cacheManager() {return new ConcurrentMapCacheManager();}
}
@Value
注入配置值:
@Component
public class AppProperties {@Value("${app.name}")private String appName;@Value("${app.version:1.0}")private String appVersion;@Value("#{systemProperties['user.name']}")private String userName;
}
@ConfigurationProperties
類型安全的配置綁定:
@ConfigurationProperties(prefix = "app.database")
@Component
public class DatabaseProperties {private String url;private String username;private String password;private int maxPoolSize = 10;// getter和setter方法public String getUrl() { return url; }public void setUrl(String url) { this.url = url; }public String getUsername() { return username; }public void setUsername(String username) { this.username = username; }public String getPassword() { return password; }public void setPassword(String password) { this.password = password; }public int getMaxPoolSize() { return maxPoolSize; }public void setMaxPoolSize(int maxPoolSize) { this.maxPoolSize = maxPoolSize; }
}
對應的配置文件:
app:database:url: jdbc:mysql://localhost:3306/mydbusername: rootpassword: passwordmax-pool-size: 20
6. 條件注解
@Conditional系列
根據條件創建Bean:
@Configuration
public class ConditionalConfig {@Bean@ConditionalOnProperty(name = "feature.enabled", havingValue = "true")public FeatureService featureService() {return new FeatureServiceImpl();}@Bean@ConditionalOnClass(RedisTemplate.class)public RedisService redisService() {return new RedisServiceImpl();}@Bean@ConditionalOnMissingBeanpublic DefaultService defaultService() {return new DefaultServiceImpl();}
}
7. 測試注解
@SpringBootTest
集成測試:
@SpringBootTest
@TestPropertySource(locations = "classpath:test.properties")
class UserServiceTest {@Autowiredprivate UserService userService;@Testvoid testCreateUser() {User user = new User("John", "john@example.com");User saved = userService.save(user);assertThat(saved.getId()).isNotNull();assertThat(saved.getName()).isEqualTo("John");}
}
@WebMvcTest
Web層測試:
@WebMvcTest(UserController.class)
class UserControllerTest {@Autowiredprivate MockMvc mockMvc;@MockBeanprivate UserService userService;@Testvoid testGetUser() throws Exception {User user = new User(1L, "John");when(userService.findById(1L)).thenReturn(user);mockMvc.perform(get("/api/users/1")).andExpect(status().isOk()).andExpected(jsonPath("$.name").value("John"));}
}
@DataJpaTest
JPA層測試:
@DataJpaTest
class UserRepositoryTest {@Autowiredprivate TestEntityManager entityManager;@Autowiredprivate UserRepository userRepository;@Testvoid testFindByEmail() {User user = new User("John", "john@example.com");entityManager.persistAndFlush(user);Optional<User> found = userRepository.findByEmail("john@example.com");assertThat(found).isPresent();assertThat(found.get().getName()).isEqualTo("John");}
}
8. 事務注解
@Transactional
事務管理:
@Service
@Transactional
public class OrderService {@Autowiredprivate OrderRepository orderRepository;@Autowiredprivate PaymentService paymentService;@Transactional(rollbackFor = Exception.class)public Order processOrder(Order order) {// 保存訂單Order savedOrder = orderRepository.save(order);// 處理支付paymentService.processPayment(order.getPaymentInfo());return savedOrder;}@Transactional(readOnly = true)public List<Order> getOrderHistory(Long userId) {return orderRepository.findByUserId(userId);}
}
9. 異步處理注解
@Async
異步方法執行:
@Service
public class EmailService {@Asyncpublic CompletableFuture<Void> sendEmail(String to, String subject, String body) {// 模擬發送郵件try {Thread.sleep(1000);System.out.println("Email sent to: " + to);} catch (InterruptedException e) {Thread.currentThread().interrupt();}return CompletableFuture.completedFuture(null);}
}@Configuration
@EnableAsync
public class AsyncConfig {@Beanpublic TaskExecutor taskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(5);executor.setMaxPoolSize(10);executor.setQueueCapacity(25);executor.setThreadNamePrefix("async-");executor.initialize();return executor;}
}
10. 緩存注解
@Cacheable、@CacheEvict、@CachePut
@Service
public class UserService {@Cacheable(value = "users", key = "#id")public User findById(Long id) {// 從數據庫查詢return userRepository.findById(id);}@CachePut(value = "users", key = "#user.id")public User update(User user) {return userRepository.save(user);}@CacheEvict(value = "users", key = "#id")public void delete(Long id) {userRepository.deleteById(id);}@CacheEvict(value = "users", allEntries = true)public void clearCache() {// 清除所有緩存}
}
11. 定時任務注解
@Scheduled
定時任務:
@Component
@EnableScheduling
public class ScheduledTasks {@Scheduled(fixedRate = 5000)public void reportCurrentTime() {System.out.println("Current time: " + new Date());}@Scheduled(cron = "0 0 1 * * ?")public void performDailyTask() {// 每天凌晨1點執行System.out.println("Daily task executed");}@Scheduled(fixedDelay = 1000, initialDelay = 2000)public void performTaskWithDelay() {// 延遲2秒后執行,之后每次執行完成后延遲1秒再執行System.out.println("Task with delay executed");}
}
12. 實際應用示例
讓我們通過一個完整的用戶管理系統來展示這些注解的綜合使用:
實體類
@Entity
@Table(name = "users")
public class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;@Column(nullable = false)private String name;@Column(unique = true, nullable = false)private String email;// 構造函數、getter、setter省略
}
Repository層
@Repository
public interface UserRepository extends JpaRepository<User, Long> {Optional<User> findByEmail(String email);List<User> findByNameContaining(String name);
}
Service層
@Service
@Transactional
public class UserService {private final UserRepository userRepository;private final EmailService emailService;public UserService(UserRepository userRepository, EmailService emailService) {this.userRepository = userRepository;this.emailService = emailService;}@Cacheable(value = "users", key = "#id")public User findById(Long id) {return userRepository.findById(id).orElseThrow(() -> new UserNotFoundException("User not found with id: " + id));}@CachePut(value = "users", key = "#result.id")public User save(User user) {User savedUser = userRepository.save(user);emailService.sendWelcomeEmail(savedUser.getEmail());return savedUser;}@CacheEvict(value = "users", key = "#id")public void delete(Long id) {userRepository.deleteById(id);}
}
Controller層
@RestController
@RequestMapping("/api/users")
@Validated
public class UserController {private final UserService userService;public UserController(UserService userService) {this.userService = userService;}@GetMappingpublic ResponseEntity<List<User>> getAllUsers(@RequestParam(defaultValue = "0") int page,@RequestParam(defaultValue = "10") int size) {Pageable pageable = PageRequest.of(page, size);Page<User> users = userService.findAll(pageable);return ResponseEntity.ok(users.getContent());}@GetMapping("/{id}")public ResponseEntity<User> getUser(@PathVariable Long id) {User user = userService.findById(id);return ResponseEntity.ok(user);}@PostMappingpublic ResponseEntity<User> createUser(@Valid @RequestBody User user) {User savedUser = userService.save(user);return ResponseEntity.status(HttpStatus.CREATED).body(savedUser);}@PutMapping("/{id}")public ResponseEntity<User> updateUser(@PathVariable Long id, @Valid @RequestBody User user) {user.setId(id);User updatedUser = userService.save(user);return ResponseEntity.ok(updatedUser);}@DeleteMapping("/{id}")public ResponseEntity<Void> deleteUser(@PathVariable Long id) {userService.delete(id);return ResponseEntity.noContent().build();}
}
總結
Spring Boot的注解系統極大地簡化了Java企業級應用的開發。通過合理使用這些注解,我們可以:
- 簡化配置:減少XML配置文件,使用注解進行聲明式配置
- 提高開發效率:自動裝配、自動配置等特性減少了樣板代碼
- 增強可讀性:注解直觀地表達了代碼的意圖和功能
- 便于測試:豐富的測試注解支持各種測試場景
- 功能強大:涵蓋了從基礎的依賴注入到高級的緩存、異步處理等功能
Spring Boot 注解對比表格
注解 | 標注位置 | 功能 |
---|---|---|
@SpringBootApplication | 類 | Spring Boot應用主類標識,包含@Configuration、@EnableAutoConfiguration、@ComponentScan |
@EnableAutoConfiguration | 類 | 開啟Spring Boot自動配置功能 |
@SpringBootConfiguration | 類 | 標識配置類,繼承自@Configuration |
@Component | 類 | 標識Spring管理的通用組件 |
@Service | 類 | 標識業務層組件,語義化的@Component |
@Repository | 類 | 標識數據訪問層組件,提供異常轉換 |
@Controller | 類 | 標識MVC控制器組件,返回視圖 |
@RestController | 類 | 標識RESTful控制器,組合@Controller和@ResponseBody |
@Autowired | 字段、方法、構造函數 | 自動依賴注入 |
@Qualifier | 字段、方法參數 | 指定注入特定名稱的Bean |
@Primary | 類、方法 | 標識優先注入的Bean |
@RequestMapping | 類、方法 | 通用HTTP請求映射 |
@GetMapping | 方法 | GET請求映射,@RequestMapping的簡化版 |
@PostMapping | 方法 | POST請求映射,@RequestMapping的簡化版 |
@PutMapping | 方法 | PUT請求映射,@RequestMapping的簡化版 |
@DeleteMapping | 方法 | DELETE請求映射,@RequestMapping的簡化版 |
@PatchMapping | 方法 | PATCH請求映射,@RequestMapping的簡化版 |
@PathVariable | 方法參數 | 綁定URL路徑中的變量 |
@RequestParam | 方法參數 | 綁定HTTP請求參數 |
@RequestBody | 方法參數 | 綁定HTTP請求體到對象 |
@RequestHeader | 方法參數 | 綁定HTTP請求頭 |
@ResponseBody | 方法、類 | 將方法返回值直接寫入HTTP響應體 |
@Configuration | 類 | 標識配置類,包含@Bean方法 |
@Bean | 方法 | 在配置類中聲明Bean |
@Value | 字段、方法參數 | 注入配置屬性值 |
@ConfigurationProperties | 類 | 類型安全的配置屬性綁定 |
@ConditionalOnProperty | 類、方法 | 基于配置屬性條件創建Bean |
@ConditionalOnClass | 類、方法 | 基于類存在條件創建Bean |
@ConditionalOnMissingBean | 類、方法 | 當缺少指定Bean時創建Bean |
@ConditionalOnBean | 類、方法 | 當存在指定Bean時創建Bean |
@SpringBootTest | 類 | 標識Spring Boot集成測試類 |
@WebMvcTest | 類 | 標識Web層測試類,只加載MVC相關組件 |
@DataJpaTest | 類 | 標識JPA層測試類,只加載JPA相關組件 |
@MockBean | 字段 | 在測試中創建Mock Bean |
@TestPropertySource | 類 | 指定測試配置文件 |
@Transactional | 類、方法 | 聲明事務邊界 |
@Async | 方法 | 標識異步執行方法 |
@EnableAsync | 類 | 開啟異步處理功能 |
@Cacheable | 方法 | 緩存方法返回結果 |
@CacheEvict | 方法 | 清除緩存 |
@CachePut | 方法 | 更新緩存 |
@EnableCaching | 類 | 開啟緩存功能 |
@Scheduled | 方法 | 標識定時任務方法 |
@EnableScheduling | 類 | 開啟定時任務功能 |
@Valid | 方法參數 | 開啟JSR-303驗證 |
@Validated | 類、方法參數 | 開啟Spring驗證功能 |
@CrossOrigin | 類、方法 | 配置跨域資源共享(CORS) |
@Profile | 類、方法 | 指定特定環境下才激活 |
@Import | 類 | 導入其他配置類 |
@ComponentScan | 類 | 配置組件掃描路徑 |
@PropertySource | 類 | 指定屬性文件位置 |
@Order | 類、方法 | 指定組件加載順序 |
@EventListener | 方法 | 標識事件監聽器方法 |
@PostConstruct | 方法 | Bean初始化后執行的方法 |
@PreDestroy | 方法 | Bean銷毀前執行的方法 |