Spring、Spring MVC和Spring Boot常用注解总结

目录

引言

Spring框架是Java企业级开发中最流行的框架之一,它通过注解的方式极大地简化了开发流程,提高了开发效率。本文将系统地总结Spring、Spring MVC和Spring Boot中常用的注解,帮助开发者快速掌握这些注解的用法,为面试做好准备。

Spring核心注解

1. 组件注册相关注解

@Component

作用:标记一个类为Spring组件,使其被自动扫描并注册到Spring容器中。

示例

@Component
public class UserService {
    // 业务逻辑
}

解析

  • @Component是通用注解,表示该类是Spring管理的组件
  • Spring会自动创建这个类的实例并管理其生命周期

@Repository

作用:标记数据访问层组件,是@Component的特化。

示例

@Repository
public class UserRepository {
    // 数据访问逻辑
}

解析

  • 用于DAO层,具有将数据库异常转换为Spring的DataAccessException的功能
  • 语义化更强,表明这是一个数据仓库
  • 它的作用是将类识别为 Bean,并交由 Spring 容器管理。然而,仅仅在接口上使用 @Repository 注解并不足以创建 Bean,必须配合 @MapperScannerConfigurer 来扫描 Mapper 接口,从而生成相应的动态代理类。(即@Repository注解不能单独使用!)
    例如:

注意:@Mapper 是 MyBatis 自带的注解,不是spring的注解,可以单独使用如果项目中有多个 Mapper 接口,可以在启动类上使用 @MapperScan 注解来自动扫描所有的 Mapper 接口,这样就无需在每个接口上单独添加注解。例如:

@SpringBootApplication
@MapperScan("com.shenlei.mapper")
public class DemoApplication {
public static void main(String[] args) {
  SpringApplication.run(DemoApplication.class, args);
    }
}

@Service

作用:标记业务逻辑层组件,是@Component的特化。

示例

@Service
public class UserService {
    // 业务逻辑
}

解析

  • 用于服务层,没有添加额外的功能
  • 主要用于明确表示该类的角色是服务层组件

@Controller

作用:标记表现层控制器组件,是@Component的特化。

示例

@Controller
public class UserController {
    // 处理HTTP请求
}

解析

  • 用于控制器层,处理HTTP请求
  • 通常与@RequestMapping等注解一起使用

@Configuration

作用:标记配置类,替代XML配置文件。

示例

@Configuration
public class AppConfig {
    
    @Bean
    public UserService userService() {
        return new UserService();
    }
}

解析

  • 表示这个类是一个配置类,包含Bean定义,可以用AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext来加载配置类,然后获取里面的bean
  • Spring会使用CGLIB创建该类的子类,拦截方法调用以实现单例管理
  • 除了注册bean,还有一些更高级的用法,包括但是不限于组件扫描、导入其他配置类、条件配置、配置webConfig等
    Configuration注解详解https://blog.csdn.net/xycxycooo/article/details/142361572

2. 依赖注入相关注解

@Autowired

作用:自动装配依赖的Bean。

示例

@Service
public class UserService {
    
    @Autowired
    private UserRepository userRepository;
    
    // 构造器注入
    @Autowired
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
}

解析

  • 默认按类型装配(byType)
  • 可用于字段、构造器、Setter方法
  • 默认情况下要求依赖必须存在,可通过required=false设置为非必须

@Qualifier

作用:当有多个相同类型的Bean时,指定注入哪一个。

示例

@Service
public class UserService {
    
    @Autowired
    @Qualifier("mysqlUserRepository")
    private UserRepository userRepository;
}

解析

  • 与@Autowired配合使用,通过名称指定要注入的Bean
  • 解决自动装配时的歧义性问题

@Resource

作用:按名称注入Bean,是JSR-250规范的注解。

示例

@Service
public class UserService {
    
    @Resource(name = "mysqlUserRepository")
    private UserRepository userRepository;
}

解析

  • 默认按名称装配(byName),如未指定名称则按类型装配
  • 是Java标准规范的一部分,不是Spring特有的

@Value

作用:注入外部化配置的值。

示例

@Service
public class UserService {
    
    @Value("${app.name}")
    private String appName;
    
    @Value("#{systemProperties['user.region']}")
    private String region;
}

解析

  • ${...}用于注入属性文件中的值
  • #{...}用于注入SpEL表达式结果

3. Bean配置相关注解

@Bean

作用:在配置类中定义一个Bean。

示例

@Configuration
public class AppConfig {
    
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
    
    @Bean(name = "userService", initMethod = "init", destroyMethod = "cleanup")
    public UserService userService() {
        return new UserService();
    }
}

解析

  • 方法的返回值会被注册为Spring容器中的Bean
  • 可指定Bean的名称、初始化方法和销毁方法
  • 方法体内的代码用于构造Bean实例

@Scope

作用:定义Bean的作用域。

示例

@Component
@Scope("prototype")
public class PrototypeBean {
    // ...
}

@Bean
@Scope("singleton")
public UserService userService() {
    return new UserService();
}

解析

  • 常用的作用域有:
    • singleton(默认):单例,每个容器只有一个Bean实例
    • prototype:原型,每次请求都创建新实例
    • request:每个HTTP请求创建一个实例
    • session:每个HTTP会话创建一个实例

@Lazy

作用:指定Bean延迟初始化。

示例

@Component
@Lazy
public class LazyBean {
    // 在首次使用时才初始化
}

解析

  • 默认情况下,单例Bean在容器启动时初始化
  • 添加@Lazy后,Bean会在首次使用时才初始化
  • 可提高应用启动速度,但可能导致运行时错误延迟暴露

@Conditional

作用:条件化创建Bean。

示例

@Bean
@Conditional(WindowsCondition.class)
public WindowsService windowsService() {
    return new WindowsService();
}

解析

  • 只有当条件满足时,才会创建Bean
  • Spring Boot扩展了多种条件注解,如@ConditionalOnProperty、@ConditionalOnClass等

Spring MVC注解

1. 控制器相关注解

@Controller

作用:标记一个类为Spring MVC控制器。

示例

@Controller
public class UserController {
    // 处理HTTP请求的方法
}

解析

  • 是@Component的特化,用于表现层
  • 处理HTTP请求,返回视图

@RestController

作用:组合注解,等同于@Controller + @ResponseBody。

示例

@RestController
public class UserApiController {
    
    @GetMapping("/users")
    public List<User> getUsers() {
        // 返回用户列表,会自动转换为JSON
        return userService.findAll();
    }
}

解析

  • 用于构建RESTful API
  • 方法返回的对象会自动转换为HTTP响应体(通常是JSON)
  • 不需要在每个方法上添加@ResponseBody

@RequestMapping

作用:映射HTTP请求到控制器的方法。

示例

@Controller
@RequestMapping("/users")
public class UserController {
    
    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public String getUser(@PathVariable Long id, Model model) {
        // 处理请求
        return "userDetail";
    }
}

解析

  • 可用于类或方法级别
  • 支持多种属性:value(路径)、method(HTTP方法)、params、headers、consumes、produces等

@GetMapping / @PostMapping / @PutMapping / @DeleteMapping / @PatchMapping

作用:@RequestMapping的HTTP方法特化版本。

示例

@RestController
@RequestMapping("/api/users")
public class UserApiController {
    
    @GetMapping
    public List<User> getAllUsers() {
        // 获取所有用户
    }
    
    @PostMapping
    public User createUser(@RequestBody User user) {
        // 创建用户
    }
    
    @PutMapping("/{id}")
    public User updateUser(@PathVariable Long id, @RequestBody User user) {
        // 更新用户
    }
    
    @DeleteMapping("/{id}")
    public void deleteUser(@PathVariable Long id) {
        // 删除用户
    }
}

解析

  • 使代码更简洁,语义更明确
  • 分别对应HTTP的GET、POST、PUT、DELETE、PATCH方法

2. 请求参数绑定注解

@RequestParam

作用:绑定请求参数到方法参数。

示例

@GetMapping("/search")
public String searchUsers(
    @RequestParam(value = "name", defaultValue = "") String name,
    @RequestParam(value = "page", required = false, defaultValue = "1") int page,
    Model model
) {
    // 处理请求
    return "searchResults";
}

解析

  • 用于获取查询参数、表单参数
  • 支持设置默认值、是否必须等属性
  • 支持简单类型自动转换(如String到int)

@PathVariable

作用:绑定URL路径变量到方法参数。

示例

@GetMapping("/users/{id}/posts/{postId}")
public String getUserPost(
    @PathVariable Long id,
    @PathVariable("postId") Long postId,
    Model model
) {
    // 处理请求
    return "userPost";
}

解析

  • 用于获取RESTful风格URL中的路径变量
  • 变量名默认与参数名相同,可通过value属性指定

@RequestBody

作用:将HTTP请求体绑定到方法参数。

示例

@PostMapping("/users")
public ResponseEntity<User> createUser(@RequestBody User user) {
    User savedUser = userService.save(user);
    return ResponseEntity.ok(savedUser);
}

解析

  • 通常用于处理Content-Type为application/json的请求
  • 使用HTTP消息转换器将请求体转换为Java对象
  • 常用于RESTful API中

@RequestHeader

作用:绑定HTTP请求头到方法参数。

示例

@GetMapping("/greeting")
public String greeting(
    @RequestHeader("User-Agent") String userAgent,
    @RequestHeader(value = "Accept-Language", required = false) String language
) {
    // 处理请求
    return "greeting";
}

解析

  • 用于获取HTTP请求头信息
  • 支持设置是否必须、默认值等属性

3. 响应处理注解

@ResponseBody

作用:将方法返回值直接作为HTTP响应体。

示例

@Controller
public class UserController {
    
    @GetMapping("/api/users/{id}")
    @ResponseBody
    public User getUser(@PathVariable Long id) {
        return userService.findById(id);
    }
}

解析

  • 返回的对象会通过HTTP消息转换器转换为响应体(通常是JSON)
  • 不再走视图解析流程
  • @RestController注解包含了此功能

@ResponseStatus

作用:指定HTTP响应状态码。

示例

@PostMapping("/users")
@ResponseStatus(HttpStatus.CREATED)
public void createUser(@RequestBody User user) {
    userService.save(user);
}

解析

  • 可用于方法或异常类
  • 用于自定义HTTP响应状态码
  • 常用于RESTful API中

Spring Boot注解

1. 应用配置注解

@SpringBootApplication

作用:Spring Boot应用的入口点,是一个组合注解。

示例

@SpringBootApplication
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

解析

  • 相当于@Configuration + @EnableAutoConfiguration + @ComponentScan的组合
  • 是Spring Boot应用的核心注解
  • 启用自动配置和组件扫描

@EnableAutoConfiguration

作用:启用Spring Boot的自动配置机制。

示例

@Configuration
@EnableAutoConfiguration
public class AppConfig {
    // 配置
}

解析

  • 根据类路径上的依赖自动配置Spring应用
  • 通常不需要单独使用,已包含在@SpringBootApplication中

@ConfigurationProperties

作用:将配置文件中的属性绑定到Java对象。

示例

@Component
@ConfigurationProperties(prefix = "app.mail")
public class MailProperties {
    private String host;
    private int port;
    private String username;
    private String password;
    
    // getters and setters
}

解析

  • 用于批量注入配置属性
  • 比@Value更适合绑定有层次结构的属性
  • 支持属性验证、类型转换等功能

@EnableConfigurationProperties

作用:启用@ConfigurationProperties注解的支持。

示例

@Configuration
@EnableConfigurationProperties(MailProperties.class)
public class MailConfiguration {
    // 配置
}

解析

  • 使指定的@ConfigurationProperties类生效
  • Spring Boot自动配置已启用此功能,通常不需要手动添加

2. 条件注解

@ConditionalOnProperty

作用:根据配置属性条件化创建Bean。

示例

@Bean
@ConditionalOnProperty(name = "app.scheduling.enabled", havingValue = "true")
public TaskScheduler taskScheduler() {
    return new ThreadPoolTaskScheduler();
}

解析

  • 当指定的属性存在且值匹配时,条件成立
  • 用于根据配置开关功能

@ConditionalOnClass / @ConditionalOnMissingClass

作用:根据类是否存在条件化创建Bean。

示例

@Bean
@ConditionalOnClass(name = "org.springframework.data.redis.core.RedisTemplate")
public RedisService redisService() {
    return new RedisService();
}

解析

  • 当类路径上有/没有指定的类时,条件成立
  • 用于根据依赖情况决定是否启用某功能

@ConditionalOnBean / @ConditionalOnMissingBean

作用:根据Bean是否存在条件化创建Bean。

示例

@Bean
@ConditionalOnMissingBean
public DataSource defaultDataSource() {
    return new EmbeddedDatabaseBuilder().build();
}

解析

  • 当容器中有/没有指定的Bean时,条件成立
  • 用于提供默认实现,但允许用户覆盖

@Profile

作用:根据激活的profile条件化创建Bean。

示例

@Configuration
@Profile("dev")
public class DevConfig {
    // 开发环境配置
}

@Bean
@Profile("prod")
public DataSource productionDataSource() {
    // 生产环境数据源
}

解析

  • 当指定的profile被激活时,相关Bean才会被创建
  • 用于区分开发、测试、生产环境配置

数据访问注解

1. Spring Data JPA注解

@Entity

作用:标记一个类为JPA实体。

示例

@Entity
@Table(name = "users")
public class User {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(name = "username", nullable = false, unique = true)
    private String username;
    
    // 其他属性和方法
}

解析

  • 表示这个类映射到数据库表
  • 通常与@Table、@Id等注解一起使用

@Repository

作用:标记一个接口为数据访问组件。

示例

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    
    List<User> findByUsername(String username);
    
    @Query("SELECT u FROM User u WHERE u.email = ?1")
    User findByEmail(String email);
}

解析

  • Spring Data JPA会自动实现这个接口
  • 提供基本的CRUD操作和分页功能
  • 支持方法名查询和@Query注解

2. 事务管理注解

@Transactional

作用:声明事务边界。

示例

@Service
public class UserService {
    
    @Transactional
    public void createUserWithRoles(User user, List<Role> roles) {
        userRepository.save(user);
        for (Role role : roles) {
            role.setUser(user);
            roleRepository.save(role);
        }
    }
    
    @Transactional(readOnly = true)
    public User findById(Long id) {
        return userRepository.findById(id)
            .orElseThrow(() -> new EntityNotFoundException("User not found"));
    }
}

解析

  • 可用于类或方法级别
  • 支持配置传播行为、隔离级别、超时、只读等属性
  • 默认对运行时异常回滚,对受检异常不回滚

总结

问:Spring框架中最常用的注解有哪些,它们的作用是什么?

关键知识点

Spring框架的常用注解可以分为以下几类:

  1. 组件注册:@Component、@Service、@Repository、@Controller等用于将类注册到Spring容器
  2. 依赖注入:@Autowired、@Resource、@Value等用于注入依赖
  3. 配置相关:@Configuration、@Bean用于Java配置
  4. MVC相关:@RequestMapping、@GetMapping等用于处理Web请求
  5. Spring Boot:@SpringBootApplication、@EnableAutoConfiguration等简化配置
  6. 数据访问:@Entity、@Transactional等用于数据库操作

深入解析

  1. 核心原理

    • Spring注解的工作原理是基于反射和AOP
    • 注解本身只是元数据,需要注解处理器来解析和处理
    • Spring通过BeanPostProcessor机制处理大部分注解
  2. 依赖注入的区别

    • @Autowired是Spring特有的,默认按类型装配
    • @Resource是JSR-250规范,默认按名称装配
    • @Inject是JSR-330规范,功能类似@Autowired
  3. 补充

    • @Component和@Bean的区别:@Component用于类,自动扫描;@Bean用于方法,显式声明
    • @Controller和@RestController的区别:后者组合了@ResponseBody,直接返回数据而非视图
    • 事务传播行为:REQUIRED(默认)、REQUIRES_NEW、NESTED等不同传播行为的应用场景
    • @Conditional注解的作用:实现条件化装配,是Spring Boot自动配置的核心机制
    • @Repository@Mapper的区别
      相同点:@Mapper 和 @Repository 都是用于标识 DAO 层接口,使其生成代理对象 Bean,并由 Spring 容器管理。对于 MyBatis 来说,使用这两个注解都可以避免编写 Mapper XML 文件。
      不同点: @Mapper 可以单独使用,且不需要配置扫描地址,是mybatis的注解而不是spring的。如果有多个 Mapper 文件,可以在启动类中添加 @MapperScan 注解来指定扫描路径。 @Repository 不能单独使用,必须配置扫描地址,否则会报错。要想使用 @Repository,必须通过 @MapperScannerConfigurer 来配置扫描路径。
  4. 建议

    • 构造器注入优于字段注入,便于测试和确保必要依赖
    • 使用@Transactional时注意代理机制的限制
    • Spring Boot条件注解可以实现灵活的配置切换