Spring常用注解总结
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框架的常用注解可以分为以下几类:
- 组件注册:@Component、@Service、@Repository、@Controller等用于将类注册到Spring容器
- 依赖注入:@Autowired、@Resource、@Value等用于注入依赖
- 配置相关:@Configuration、@Bean用于Java配置
- MVC相关:@RequestMapping、@GetMapping等用于处理Web请求
- Spring Boot:@SpringBootApplication、@EnableAutoConfiguration等简化配置
- 数据访问:@Entity、@Transactional等用于数据库操作
深入解析
-
核心原理:
- Spring注解的工作原理是基于反射和AOP
- 注解本身只是元数据,需要注解处理器来解析和处理
- Spring通过BeanPostProcessor机制处理大部分注解
-
依赖注入的区别:
- @Autowired是Spring特有的,默认按类型装配
- @Resource是JSR-250规范,默认按名称装配
- @Inject是JSR-330规范,功能类似@Autowired
-
补充:
- @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 来配置扫描路径。
-
建议:
- 构造器注入优于字段注入,便于测试和确保必要依赖
- 使用@Transactional时注意代理机制的限制
- Spring Boot条件注解可以实现灵活的配置切换