Spring Boot注解详解

发布于:2025-07-22 ⋅ 阅读:(15) ⋅ 点赞:(0)


前言

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 {
    @Bean
    public 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 {
    @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请求:

@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 {
    
    @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

自动装配依赖:

@Service
public 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时,指定具体注入哪个:

@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 {
    
    @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

标识配置类:

@Configuration
public 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:

@Configuration
public class AppConfig {
    
    @Bean
    public 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/mydb
    username: root
    password: password
    max-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
    @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层测试:

@DataJpaTest
class 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
@Transactional
public 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

异步方法执行:

@Service
public 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
@EnableAsync
public 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

@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;
    }
    
    @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企业级应用的开发。通过合理使用这些注解,我们可以:

  1. 简化配置:减少XML配置文件,使用注解进行声明式配置
  2. 提高开发效率:自动装配、自动配置等特性减少了样板代码
  3. 增强可读性:注解直观地表达了代码的意图和功能
  4. 便于测试:丰富的测试注解支持各种测试场景
  5. 功能强大:涵盖了从基础的依赖注入到高级的缓存、异步处理等功能

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销毁前执行的方法

网站公告

今日签到

点亮在社区的每一天
去签到