Spring Boot注解详解_springboot注入注解
文章目录
-
- 前言
- 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最核心的注解,它是一个组合注解,包含了:
@SpringBootApplicationpublic class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); }}
等价于以下三个注解的组合:
@SpringBootConfiguration
:标识这是一个配置类@EnableAutoConfiguration
:开启自动配置@ComponentScan
:开启组件扫描
@EnableAutoConfiguration
自动配置是Spring Boot的核心特性,它会根据类路径下的依赖自动配置Bean:
@EnableAutoConfiguration@ComponentScanpublic class ManualConfiguration { // 手动配置类}
@SpringBootConfiguration
继承自@Configuration
,用于标识配置类:
@SpringBootConfigurationpublic class AppConfig { @Bean public MyService myService() { return new MyServiceImpl(); }}
2. 组件注解
@Component及其衍生注解
@Component
最基础的组件注解,标识一个Spring管理的组件:
@Componentpublic class DataProcessor { public void process(String data) { // 处理逻辑 }}
@Service
业务层组件,语义化更强:
@Servicepublic class UserService { public User findById(Long id) { // 业务逻辑 return new User(); }}
@Repository
数据访问层组件,提供异常转换功能:
@Repositorypublic class UserRepository { @Autowired private JdbcTemplate jdbcTemplate; public List<User> findAll() { return jdbcTemplate.query(\"SELECT * FROM users\", (rs, rowNum) -> new User(rs.getLong(\"id\"), rs.getString(\"name\"))); }}
@Controller
控制器组件,处理HTTP请求:
@Controllerpublic class UserController { @GetMapping(\"/users\") public String listUsers(Model model) { // 返回视图名称 return \"user-list\"; }}
@RestController
RESTful控制器,结合了@Controller
和@ResponseBody
:
@RestController@RequestMapping(\"/api/users\")public class UserRestController { @Autowired private UserService userService; @GetMapping public List<User> getAllUsers() { return userService.findAll(); } @PostMapping public User createUser(@RequestBody User user) { return userService.save(user); }}
3. 依赖注入注解
@Autowired
自动装配依赖:
@Servicepublic class OrderService { // 字段注入 @Autowired private UserService userService; // 构造函数注入(推荐) private final PaymentService paymentService; @Autowired public OrderService(PaymentService paymentService) { this.paymentService = paymentService; } // Setter注入 private EmailService emailService; @Autowired public void setEmailService(EmailService emailService) { this.emailService = emailService; }}
@Qualifier
当有多个同类型Bean时,指定具体注入哪个:
@Servicepublic class NotificationService { @Autowired @Qualifier(\"emailSender\") private MessageSender emailSender; @Autowired @Qualifier(\"smsSender\") private MessageSender smsSender;}
@Primary
标识优先注入的Bean:
@Component@Primarypublic 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 { @GetMapping public List<Book> getAllBooks() { return bookService.findAll(); } @GetMapping(\"/{id}\") public Book getBook(@PathVariable Long id) { return bookService.findById(id); } @PostMapping public 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
标识配置类:
@Configurationpublic class DatabaseConfig { @Bean @Primary public DataSource primaryDataSource() { return DataSourceBuilder.create() .url(\"jdbc:mysql://localhost:3306/primary\") .build(); } @Bean public DataSource secondaryDataSource() { return DataSourceBuilder.create() .url(\"jdbc:mysql://localhost:3306/secondary\") .build(); }}
@Bean
声明Bean:
@Configurationpublic class AppConfig { @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean @ConditionalOnProperty(name = \"app.cache.enabled\", havingValue = \"true\") public CacheManager cacheManager() { return new ConcurrentMapCacheManager(); }}
@Value
注入配置值:
@Componentpublic 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\")@Componentpublic 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/mydb username: root password: password max-pool-size: 20
6. 条件注解
@Conditional系列
根据条件创建Bean:
@Configurationpublic 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 @ConditionalOnMissingBean public DefaultService defaultService() { return new DefaultServiceImpl(); }}
7. 测试注解
@SpringBootTest
集成测试:
@SpringBootTest@TestPropertySource(locations = \"classpath:test.properties\")class UserServiceTest { @Autowired private UserService userService; @Test void 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 { @Autowired private MockMvc mockMvc; @MockBean private UserService userService; @Test void 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层测试:
@DataJpaTestclass UserRepositoryTest { @Autowired private TestEntityManager entityManager; @Autowired private UserRepository userRepository; @Test void 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@Transactionalpublic class OrderService { @Autowired private OrderRepository orderRepository; @Autowired private 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
异步方法执行:
@Servicepublic class EmailService { @Async public 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@EnableAsyncpublic class AsyncConfig { @Bean public 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
@Servicepublic 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@EnableSchedulingpublic 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层
@Repositorypublic interface UserRepository extends JpaRepository<User, Long> { Optional<User> findByEmail(String email); List<User> findByNameContaining(String name);}
Service层
@Service@Transactionalpublic 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\")@Validatedpublic class UserController { private final UserService userService; public UserController(UserService userService) { this.userService = userService; } @GetMapping public 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); } @PostMapping public 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
@EnableAutoConfiguration
@SpringBootConfiguration
@Component
@Service
@Repository
@Controller
@RestController
@Autowired
@Qualifier
@Primary
@RequestMapping
@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping
@PathVariable
@RequestParam
@RequestBody
@RequestHeader
@ResponseBody
@Configuration
@Bean
@Value
@ConfigurationProperties
@ConditionalOnProperty
@ConditionalOnClass
@ConditionalOnMissingBean
@ConditionalOnBean
@SpringBootTest
@WebMvcTest
@DataJpaTest
@MockBean
@TestPropertySource
@Transactional
@Async
@EnableAsync
@Cacheable
@CacheEvict
@CachePut
@EnableCaching
@Scheduled
@EnableScheduling
@Valid
@Validated
@CrossOrigin
@Profile
@Import
@ComponentScan
@PropertySource
@Order
@EventListener
@PostConstruct
@PreDestroy