Springboot注解要点
Springboot注解要点
@Service注解:
-
作用对象: 用于标注在类上,通常用于业务层(Service 层)的组件。
-
功能: 将被注解的类注册为 Spring 容器中的一个 Bean,使其可被自动装配和管理。
-
使用方式: 通过类路径扫描(Component Scan),Spring 自动检测并注册带有
@Service注解的类。 -
示例:
▼java复制代码@Service public class UserService { // 业务逻辑 }
2.@Bean 注解:
-
作用对象: 用于标注在方法上。
-
功能: 将方法的返回值注册为 Spring 容器中的一个 Bean。
-
使用方式: 通常在配置类(带有
@Configuration注解的类)中使用,手动定义和配置 Bean。 -
示例:
▼java复制代码@Configuration public class AppConfig { @Bean public UserService userService() { return new UserService(); } }3.
@Autowired注解:-
作用对象: 用于构造器、方法或字段上。
-
功能: 实现自动装配,将匹配的 Bean 注入到被注解的字段、方法或构造器中。
-
使用方式: 通过类型匹配(默认)或名称匹配,将容器中的 Bean 注入到需要的地方。
-
示例:
▼java复制代码@Service public class UserService { @Autowired private UserRepository userRepository; // 业务逻辑 }
在 Spring 框架中,
@Autowired注解用于自动装配依赖,通常根据类型匹配来注入所需的 Bean。然而,当容器中存在多个相同类型的 Bean 时,Spring 可能会因为无法确定注入哪个 Bean 而抛出异常。为了解决这种歧义,我们可以采用以下策略:1)使用
@Qualifier注解指定 Bean 的名称:通过在
@Autowired注解的同时,使用@Qualifier注解明确指定要注入的 Bean 的名称。这样,Spring 会根据名称精确匹配所需的 Bean。示例:
▼java复制代码@Service public class UserService { @Autowired @Qualifier("userRepositoryImpl1") private UserRepository userRepository; // 业务逻辑 }在上述示例中,
@Qualifier("userRepositoryImpl1")明确指定了要注入的 Bean 名称为userRepositoryImpl1,从而避免了歧义。2)使用
@Primary注解设置首选的 Bean:如果希望在存在多个同类型 Bean 时,默认注入特定的一个,可以在该 Bean 上使用
@Primary注解。这样,Spring 会优先选择被标记为@Primary的 Bean 进行注入。示例:
▼java复制代码@Repository @Primary public class UserRepositoryImpl1 implements UserRepository { // 实现代码 } @Repository public class UserRepositoryImpl2 implements UserRepository { // 实现代码 }3)**结合使用
@Primary和@Qualifier:**在某些情况下,可能需要在全局范围内设置一个首选的 Bean,但在特定场景下仍需要注入其他 Bean。这时,可以结合使用@Primary和@Qualifier。示例:
▼java复制代码@Repository @Primary public class UserRepositoryImpl1 implements UserRepository { // 实现代码 } @Repository public class UserRepositoryImpl2 implements UserRepository { // 实现代码 } @Service public class UserService { @Autowired private UserRepository userRepository; // 默认注入 UserRepositoryImpl1 @Autowired @Qualifier("userRepositoryImpl2") private UserRepository anotherUserRepository; // 注入 UserRepositoryImpl2 // 业务逻辑 } -
5.@Transactional
作用:用于声明事务管理。标注在类或方法上,表示该类的所有方法或特定方法需要在事务中执行。管理数据库事务。它确保一系列数据库操作要么全部成功提交,要么在出现错误时全部回滚,保持数据的一致性。
使用场景: 在需要确保数据一致性和完整性的业务逻辑中,特别是涉及数据库操作时,使用 @Transactional 可以自动管理事务的开启、提交和回滚。
示例:
▼java复制代码@Service public class UserService { @Transactional public void createUser(User user) { // 数据库操作,例如插入用户记录 } }
通俗解释:想象去银行转账,涉及扣款和存款两个步骤。@Transactional 就像一个保障机制,确保这两个步骤要么都成功(钱成功从一个账户转到另一个账户),要么都失败(如果任何一步出错,所有操作都回滚),以防止出现钱扣了但未成功存入的情况。
6.@Scheduled
作用: 用于声明一个方法是计划任务,按照指定的时间间隔或Cron表达式执行。
使用场景: 在需要定期执行某些任务(如数据备份、定时报告生成等)时,使用 @Scheduled 注解定义这些任务的执行计划。
示例:
▼java复制代码@Component public class ScheduledTasks { @Scheduled(fixedRate = 5000) public void reportCurrentTime() { // 每隔5秒执行一次的任务 } }
reportCurrentTime 方法将每隔5秒执行一次。
7.@EnableAspectJAutoProxy:
-
作用: 开启 Spring 对 AspectJ 注解(如
@Aspect)的自动代理支持。 -
使用位置: 通常标注在配置类上,指示 Spring 容器扫描并处理带有
@Aspect注解的类。 -
通俗解释: 这相当于打开了 AOP 功能的开关,使得 Spring 能够识别并处理切面类。
8.@Aspect:
- 作用: 将一个类声明为切面,定义横切关注点(如日志记录、事务管理等)。
- 使用位置: 标注在具体的类上,该类包含了切点和通知等 AOP 相关的定义。
- 通俗解释: 这就像是定义了一个特殊的模块,用于在程序的特定位置添加额外的功能。
▼java复制代码@Configuration @EnableAspectJAutoProxy public class AppConfig { // 配置类内容 }
▼java复制代码@Aspect @Component public class LoggingAspect { @Before("execution(* com.example.service.*.*(..))") public void logBeforeMethod(JoinPoint joinPoint) { // 在目标方法执行前执行的操作 } }
9.@EnableCaching
- 作用: 这是一个配置注解,用于在 Spring 应用中启用缓存支持。
- 通俗解释: 想象您的系统是一个现代企业仓库,@EnableCaching 就像是打开了自动仓储管理系统的总开关,只有打开这个开关后,其他缓存操作才能生效。
- 使用场景: 通常在配置类或主启动类上添加此注解。
@Cacheable
-
作用: 标记在方法上,用于将方法的返回值缓存起来。当方法被再次调用且参数一致时,直接从缓存中返回结果,而不是再次执行方法体。
-
通俗解释: 就像企业里常用的“记忆盒子”:第一次执行后把结果存起来,以后再遇到同样的问题,就可以直接拿出“记忆盒子”里的答案,而不必重新思考。
-
▼java复制代码
@Cacheable(value = "users", key = "#id") public User getUserById(Long id) { // 模拟耗时操作,比如数据库查询 return userRepository.findById(id); }
@CacheEvict
-
作用: 用于清除缓存。当数据发生变化(比如更新或删除操作),需要清除相关的缓存数据,以防止缓存数据过时。
-
通俗解释: 就好比您在企业中更新了库存信息,那么原来的“记忆盒子”里的数据就不再准确,需要及时清空或更新,以免给后续操作带来错误。
-
▼java复制代码
@CacheEvict(value = "users", key = "#id") public void deleteUser(Long id) { userRepository.deleteById(id); }
@CachePut
-
作用: 用于更新缓存。与 @Cacheable 不同的是,@CachePut 不会阻止方法执行,而是在方法执行后将返回值更新到缓存中。
- 通俗解释: 想象您修改了某个产品的详细信息,@CachePut 会确保您每次修改后,都将最新的“产品信息”写入“记忆盒子”,保证后续查询拿到的是最新数据。
-
▼java复制代码
@CachePut(value = "users", key = "#user.id") public User updateUser(User user) { // 执行更新操作 return userRepository.save(user); }
10.@Controller
作用: 标记一个类为 Spring MVC 控制器,负责接收 Web 请求并返回视图。
通俗解释: 就像企业前台接待员,负责接收客户(请求)并将其分发到相应部门(业务逻辑)处理。
示例:
▼java复制代码@Controller public class HomeController { @RequestMapping("/home") public String home(Model model) { model.addAttribute("message", "欢迎来到企业主页!"); return "home"; // 返回视图名称,例如一个 JSP 或 Thymeleaf 模板 } }
11.@EnableWebSecurity
作用: 启用 Spring Security 的 Web 安全支持,配置安全过滤器链,保护应用资源。
通俗解释: 类似于为办公楼安装门禁系统,确保只有有权限的人才能进入
▼java复制代码@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .anyRequest().authenticated() // 所有请求需要认证 .and() .formLogin().loginPage("/login").permitAll() // 自定义登录页面 .and() .logout().permitAll(); } }
12.@Secured
作用: 用于方法级安全控制,通过指定角色(如 "ROLE_ADMIN")限制访问。
通俗解释: 就像某份机密文件只有特定级别的员工才能查看。
▼java复制代码@Service public class AdminService { @Secured("ROLE_ADMIN") public void performAdminTask() { // 仅允许管理员执行的任务 System.out.println("执行管理员任务"); } }
13.@PreAuthorize
作用: 同样用于方法级安全控制,但支持复杂的权限表达式判断。
通俗解释: 类似于进入会议室不仅需要门禁卡,还需要会议预约,条件更灵活。
▼java复制代码@Service public class UserService { @PreAuthorize("#userId == authentication.principal.id or hasRole('ROLE_ADMIN')") public void updateUser(Long userId, User user) { // 只有用户本人或管理员才能更新用户信息 System.out.println("更新用户信息"); } }
14.@RestControllerAdvice
作用: 用于全局异常处理、数据绑定等,为 REST 控制器提供统一处理机制。
通俗解释: 就像企业客户服务中心,统一处理所有客户投诉(异常)。
▼java复制代码@RestControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(Exception.class) public ResponseEntity<String> handleException(Exception ex) { // 捕获所有异常并返回统一错误信息 return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) .body("系统错误:" + ex.getMessage()); } }
15.@Test
作用: JUnit 提供的注解,用于标识一个方法为测试方法。
通俗解释: 就像企业上线前必须经过严格的验收测试,确保系统没有问题。
▼java复制代码public class SampleTest { @Test public void testAddition() { int result = 2 + 3; assertEquals(5, result); } }
16.@MockBean
作用: 在 Spring Boot 测试中,用于创建 Mockito 模拟对象,并将其注入到 Spring 上下文,替换真实 Bean,隔离测试环境。
通俗解释: 就像用“替身演员”模拟某个部门,以便单独测试某个功能,不受其他模块影响。
▼java复制代码@SpringBootTest public class UserServiceTest { @MockBean private UserRepository userRepository; // 模拟数据访问层 @Autowired private UserService userService; @Test public void testGetUser() { User mockUser = new User(1L, "测试用户"); Mockito.when(userRepository.findById(1L)).thenReturn(Optional.of(mockUser)); User user = userService.getUserById(1L); assertEquals("测试用户", user.getName()); } }
17.@SpringBootTest
作用: 启动完整的 Spring Boot 应用上下文,用于集成测试,让测试环境尽可能接近生产环境。
通俗解释: 类似于企业大项目上线前的全员演练,确保所有系统模块都能正常协同工作。
▼java复制代码@SpringBootTest public class ApplicationIntegrationTest { @Autowired private WebApplicationContext context; @Test public void contextLoads() { // 测试 Spring Boot 应用上下文是否能正常加载 assertNotNull(context); } }
18.@DataJpaTest
作用: 针对 JPA 相关组件进行切片测试,主要用于测试 Repository 层,自动配置内存数据库,执行速度快。
通俗解释: 就像企业针对仓库管理系统做专项测试,只验证库存数据操作是否准确。
▼java复制代码@DataJpaTest public class UserRepositoryTest { @Autowired private TestEntityManager entityManager; @Autowired private UserRepository userRepository; @Test public void testFindByName() { User user = new User("测试用户"); entityManager.persist(user); entityManager.flush(); User found = userRepository.findByName("测试用户"); assertEquals(user.getName(), found.getName()); } }
19.@WebMvcTest
作用: 用于测试 Spring MVC 控制器层的切片测试,只加载 Web 层相关组件,不启动完整应用上下文,测试速度更快。
通俗解释: 类似于企业专门抽查前台服务流程,确保客户请求能被正确处理,不涉及后台数据逻辑。
▼java复制代码@WebMvcTest(HomeController.class) public class HomeControllerTest { @Autowired private MockMvc mockMvc; @Test public void testHome() throws Exception { mockMvc.perform(get("/home")) .andExpect(status().isOk()) .andExpect(view().name("home")) .andExpect(model().attributeExists("message")); } }
20.@Entity
作用: JPA 注解,用于标记一个类为持久化实体,映射到数据库中的表。
通俗解释: 就像企业中的档案柜,定义了数据存储的结构,每个实例对应一份档案记录。
▼java复制代码@Entity public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; // 构造器、getter、setter public User() {} public User(String name) { this.name = name; } // getters and setters... }
21.@Id
作用: 标识实体的主键字段,相当于企业档案编号,确保每条记录具有唯一标识。
▼java复制代码@Entity public class Employee { @Id private Long id; // 其他字段... }
22.@GeneratedValue
作用: 配合 @Id 使用,自动生成主键的值,避免手动指定。
通俗解释: 类似于系统自动生成员工编号,您不必每次都输入。
常见策略:
-
AUTO:系统自动选择合适的生成方式。
- IDENTITY:依赖数据库的自增机制生成编号。
- SEQUENCE:通过数据库序列生成(例如 Oracle 常用)。
- TABLE:使用一个专门的表来生成编号。
▼java复制代码@Entity public class Employee { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; // 其他字段... }
23.@Column
作用: 映射实体的属性到数据库表中的列,可以设置列名、长度、是否允许为空等属性。
通俗解释: 就像在员工档案中详细说明每个字段的格式和要求,比如姓名最长 100 个字符、不能为空等。
▼java复制代码@Entity public class Employee { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name = "employee_name", nullable = false, length = 100) private String name; // 其他字段... }
24.@JoinColumn
作用: 定义实体关联时所使用的外键列,用于连接两个表之间的关系。
通俗解释: 就像在员工档案中注明员工所属部门的编号,通过这个编号连接到部门档案。
▼java复制代码@Entity public class Employee { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToOne @JoinColumn(name = "department_id") private Department department; // 其他字段... }
25.@ManyToOne
作用: 定义多对一的关联关系,即多个实体实例关联到同一个目标实例。
通俗解释: 多个员工归属于同一个部门,就像很多员工共同属于一个部门经理领导下。
示例: 上面的 Employee 类示例中已经演示。
26.@OneToMany
作用: 定义一对多的关联关系,通常在“一”的一方表示一个实例关联多个其他实例。
通俗解释: 一个部门可以拥有多个员工,就像一个部门有多个成员。
▼java复制代码@Entity public class Department { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @OneToMany(mappedBy = "department") private List<Employee> employees; // 其他字段... }
27.@ManyToMany
作用: 定义多对多的关联关系,即两个实体之间相互关联,多对多关系往往需要一个中间表来记录关联。
通俗解释: 例如,员工和项目之间的关系:一个员工可以参与多个项目,一个项目也可以有多个员工,就像跨部门合作的联合工作小组。
▼java复制代码@Entity public class Employee { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToMany @JoinTable( name = "employee_project", joinColumns = @JoinColumn(name = "employee_id"), inverseJoinColumns = @JoinColumn(name = "project_id") ) private Set<Project> projects; // 其他字段... }
28.@JoinTable
作用: 与 @ManyToMany 搭配使用,定义多对多关系的中间关联表的名称及其外键映射。
通俗解释: 就像为跨部门合作建立一个专门的对接平台,记录员工与项目之间的对应关系。
示例: 参见上面的 @ManyToMany 示例,其中已经包含了 @JoinTable 的使用。
29.@MappedSuperclass
作用: 用于声明一个父类,其属性供子类继承,但该父类本身不映射为数据库表。
通俗解释: 类似于制定一个通用的档案模板,比如记录创建时间和修改时间,所有具体的档案(如员工、客户)都继承这些通用信息,但模板本身不存储在数据库中。
▼java复制代码@MappedSuperclass public abstract class BaseEntity { @Column(name = "created_at") private LocalDateTime createdAt; @Column(name = "updated_at") private LocalDateTime updatedAt; // getters and setters... } @Entity public class Employee extends BaseEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; // 其他字段... }
30.@Inheritance
作用: 用于定义实体继承的映射策略,当多个实体继承同一父类时,指定如何在数据库中存储它们之间的继承关系。
通俗解释: 就像企业中对于不同类型的员工档案,选择不同的存储策略:
- SINGLE_TABLE:所有继承的实体存储在同一张表中,通过一个类型字段区分。
- JOINED:每个子类单独一张表,通过外键与父类表关联,数据结构更清晰,但查询时需要连接操作。
- TABLE_PER_CLASS:每个子类都有独立的表,表中包含所有父类属性,数据相对独立。
▼java复制代码@Entity @Inheritance(strategy = InheritanceType.JOINED) public abstract class Person { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; // 通用字段,例如姓名、出生日期等 } @Entity public class Employee extends Person { private String department; // 其他字段... } @Entity public class Customer extends Person { private String loyaltyLevel; // 其他字段... }
事务与审计相关
31.@EnableTransactionManagement
作用: 开启 Spring 的声明式事务管理,使得 @Transactional 等事务控制注解能生效。
通俗解释: 就像给重要操作加上保险,一旦操作出错可以回滚,确保系统数据一致。
示例:
▼java复制代码@Configuration @EnableTransactionManagement public class AppConfig { // 数据源和事务管理器的配置 }
32.@EnableJpaAuditing
作用: 启用 JPA 审计功能,让实体在创建和修改时自动记录时间(和其他审计信息)。
通俗解释: 类似于企业记录档案的“创建时间”和“修改时间”,方便追溯档案变化,启动这个功能后系统自动帮你记录。
▼java复制代码@Configuration @EnableJpaAuditing public class JpaConfig { // 配置类内容 }
33.@CreatedDate
作用: 在实体首次保存时自动填充创建时间字段(需要配合 @EnableJpaAuditing 使用)。
通俗解释: 就像档案入库时自动记录时间,告诉你这份档案何时生成。
▼java复制代码@Entity @EntityListeners(AuditingEntityListener.class) public class Document { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @CreatedDate @Column(nullable = false, updatable = false) private LocalDateTime createdDate; }
34.@LastModifiedDate
作用: 在实体更新时自动填充最后修改时间字段。
通俗解释: 就像档案更新后自动记录最新修改时间,便于查阅最近的变更信息。
▼java复制代码@Entity @EntityListeners(AuditingEntityListener.class) public class Document { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @LastModifiedDate private LocalDateTime lastModifiedDate; }
35.@PrePersist
作用: 在实体持久化(第一次存储到数据库)之前调用的方法。
通俗解释: 类似于档案入库前的最后检查,确保数据准备就绪。
▼java复制代码@Entity public class Employee { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @PrePersist public void prePersist() { System.out.println("准备将员工信息保存到数据库"); } }
36.@PreUpdate
作用: 在实体更新前调用的方法。
通俗解释: 就像在修改档案前做预检查,确保更新前所有准备工作都到位。
▼java复制代码@Entity public class Employee { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @PreUpdate public void preUpdate() { System.out.println("更新前的预处理"); } }
实体生命周期回调
@PostPersist
作用: 在实体持久化成功后调用的方法。
通俗解释: 档案入库后,系统自动通知相关人员,确认档案已成功存入数据库。
▼java复制代码@Entity public class Employee { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @PostPersist public void postPersist() { System.out.println("员工信息已保存"); } }
38.@PostUpdate
作用: 在实体更新成功后调用的方法。
通俗解释: 更新完成后自动记录或通知,确保变更已经生效。
▼java复制代码@Entity public class Employee { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @PostUpdate public void postUpdate() { System.out.println("员工信息更新成功"); } }
39.@PreRemove
作用: 在实体删除前调用的方法。
通俗解释: 在档案销毁前进行最后确认或备份,就像删除文件前的提醒。
▼java复制代码@Entity public class Employee { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @PreRemove public void preRemove() { System.out.println("员工信息即将删除"); } }
40.@PreFlush
作用: 在 EntityManager flush 前调用的方法,数据即将同步到数据库时执行。
通俗解释: 就像在把所有变更的档案正式送到仓库前,先做一次全面检查。
▼java复制代码@Entity public class Employee { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @PreFlush public void preFlush() { System.out.println("数据即将刷新到数据库"); } }
41.@PostRemove
作用: 在实体删除后调用的方法。
通俗解释: 删除档案后自动发出通知,确认档案已被清除。
▼java复制代码@Entity public class Employee { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @PostRemove public void postRemove() { System.out.println("员工信息已删除"); } }
42.@PostFlush
作用: 在 EntityManager flush 后调用的方法,数据已经写入数据库。
通俗解释: 就像档案更新后进行最后总结,确保所有操作都已顺利完成。
▼java复制代码@Entity public class Employee { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @PostFlush public void postFlush() { System.out.println("刷新操作完成"); } }
Bean 生命周期管理
43.@PostConstruct
作用: 在 Bean 初始化完成后调用,用于执行初始化逻辑。
通俗解释: 就像新员工完成入职培训后,正式开始上岗前的最后指导,确保万事俱备。
▼java复制代码@Component public class StartupBean { @PostConstruct public void init() { System.out.println("Bean 初始化完成,执行初始化逻辑"); } }
44.@PreDestroy
作用: 在 Bean 销毁之前调用,用于释放资源或进行清理工作。
通俗解释: 类似于员工离职前的交接工作,确保所有任务都妥善处理。
▼java复制代码@Component public class ShutdownBean { @PreDestroy public void cleanup() { System.out.println("Bean 将被销毁,开始清理资源"); } }
Web 请求与数据绑定
45.@RequestHeader
作用: 绑定 HTTP 请求头中的值到方法参数上。
通俗解释: 就像在接待客户时记录他们带来的“身份标签”(如浏览器信息),方便后续定制服务。
▼java复制代码@RestController public class HeaderController { @GetMapping("/header") public String getHeader(@RequestHeader("User-Agent") String userAgent) { return "User-Agent: " + userAgent; } }
46.@CookieValue
作用: 绑定 HTTP 请求中的 Cookie 值到方法参数上。
通俗解释: 就像在客户到访时,读取他们的会员卡信息,用于个性化服务。
▼java复制代码@RestController public class CookieController { @GetMapping("/cookie") public String getCookie(@CookieValue("sessionId") String sessionId) { return "Session ID: " + sessionId; } }
47.@ModelAttribute
作用:
- 方法参数上:将请求参数绑定到对象;
- 方法上:预先将数据添加到模型中,供视图使用。
通俗解释: 类似于在会议前收集所有必要的资料,确保所有与会人员都能获得所需信息。
▼java复制代码@Controller public class UserController { @ModelAttribute("commonData") public String populateCommonData() { return "共享信息"; } @GetMapping("/user") public String getUser(Model model) { model.addAttribute("user", new User("张三")); return "userView"; } }
48.@SessionAttributes
作用: 声明哪些模型属性需要保存在会话中,便于跨请求共享。
通俗解释: 就像在会议中记录下关键决策,存入“共享记事本”,后续讨论时可以引用。
▼java复制代码@Controller @SessionAttributes("user") public class SessionController { @GetMapping("/setUser") public String setUser(Model model) { model.addAttribute("user", new User("李四")); return "userView"; } }
异常处理与响应状态
49.@ExceptionHandler
作用: 定义控制器中处理特定异常的方法,实现局部异常处理。
通俗解释: 类似于企业中专门设立的客服部门,当遇到问题时有专人处理并反馈结果。
▼java复制代码@Controller public class ErrorController { @ExceptionHandler(Exception.class) public ResponseEntity<String> handleAllExceptions(Exception ex) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) .body("出错了: " + ex.getMessage()); } }
50.@ResponseStatus
作用: 用于标注方法或异常类,指定返回给客户端的 HTTP 状态码。
通俗解释: 就像在系统出错时明确标识错误类型,例如“404 未找到”,方便客户端识别和处理。
示例:
▼java复制代码@ResponseStatus(HttpStatus.NOT_FOUND) public class ResourceNotFoundException extends RuntimeException { public ResourceNotFoundException(String message) { super(message); } }
AOP 通知
51.@Around
作用: 定义环绕通知,可在目标方法执行前后添加额外逻辑,控制方法执行过程。
通俗解释: 类似于在业务流程的入口和出口都设置检查点,既可以预防问题,也能在完成后进行总结。
▼java复制代码@Aspect @Component public class LoggingAspect { @Around("execution(* com.example.service.*.*(..))") public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("方法开始: " + joinPoint.getSignature().getName()); Object result = joinPoint.proceed(); System.out.println("方法结束: " + joinPoint.getSignature().getName()); return result; } }
52.@Before
作用: 定义前置通知,在目标方法执行前运行额外逻辑。
通俗解释: 就像在正式开始业务流程前做安全检查,确保所有条件都满足。
▼java复制代码@Aspect @Component public class SecurityAspect { @Before("execution(* com.example.service.*.*(..))") public void checkSecurity(JoinPoint joinPoint) { System.out.println("安全检查开始: " + joinPoint.getSignature().getName()); } }
53.@SpringBootApplication
作用: 这是一个复合注解,包含了 @Configuration、@EnableAutoConfiguration 和 @ComponentScan,用于标记主启动类,启动整个 Spring Boot 应用。
通俗解释: 就像企业的大门和总控制中心,启动这个注解就能自动配置所有子部门,让系统一键启动,无需逐个激活。
示例:
▼java复制代码@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
@RestController
作用: 用于标记控制器类,结合 @Controller 与 @ResponseBody,专门用于构建 RESTful API,直接返回 JSON 或其他格式数据。
通俗解释: 就像公司前台专门处理外部客户的在线咨询,直接给出标准化答案,而不是去转交纸质文件。
示例:
▼java复制代码@RestController public class ApiController { @GetMapping("/hello") public String hello() { return "Hello, Spring Boot!"; } }
@RequestMapping
作用: 用于映射 HTTP 请求到指定的控制器方法上,可以在类级别和方法级别设置路径和请求方法。
通俗解释: 就像公司内部的总调度中心,根据不同的请求(例如电话或邮件)将信息分发到相应部门。
示例:
▼java复制代码@RestController @RequestMapping("/api") public class ApiController { @RequestMapping("/info") public String info() { return "API 信息"; } }
@GetMapping
作用: 是 @RequestMapping 的快捷方式,专门用于处理 HTTP GET 请求。
通俗解释: 类似于专门设置一个查询窗口,专门用于接收查询请求并返回信息。
示例:
▼java复制代码@GetMapping("/users") public List<User> getUsers() { return userService.findAll(); }
@PostMapping
作用: 用于处理 HTTP POST 请求,通常用于创建资源或提交数据。
通俗解释: 就像公司内部的提交申请窗口,接收新申请或数据,并进行处理。
示例:
▼java复制代码@PostMapping("/users") public User createUser(@RequestBody User user) { return userService.save(user); }
@PutMapping
作用: 处理 HTTP PUT 请求,通常用于更新现有资源。
通俗解释: 类似于企业中更新档案的流程,将最新数据写入已有记录中。
示例:
▼java复制代码@PutMapping("/users/{id}") public User updateUser(@PathVariable Long id, @RequestBody User user) { user.setId(id); return userService.update(user); }
@DeleteMapping
作用: 用于处理 HTTP DELETE 请求,通常用于删除资源。
通俗解释: 就像企业中删除过时档案的操作,一旦确认无用,就把档案清理出系统。
示例:
▼java复制代码@DeleteMapping("/users/{id}") public void deleteUser(@PathVariable Long id) { userService.delete(id); }
@RequestParam
作用: 将 HTTP 请求中的参数(通常是查询参数)绑定到方法参数上。
通俗解释: 就像在查询表单中填写搜索条件,系统会根据这些条件找到对应信息。
示例:
▼java复制代码@GetMapping("/search") public String search(@RequestParam("keyword") String keyword) { return "搜索关键字:" + keyword; }
@RequestBody
作用: 将 HTTP 请求体中的 JSON 或 XML 数据反序列化为 Java 对象,常用于 POST 或 PUT 请求。
通俗解释: 类似于企业接收到一份电子文档,系统自动解析文档内容并生成对应的对象,便于后续处理。
示例:
▼java复制代码@PostMapping("/users") public User createUser(@RequestBody User user) { return userService.save(user); }
@ResponseBody
作用: 将方法的返回值直接作为 HTTP 响应体返回,通常用于返回 JSON 数据,不再经过视图解析。
通俗解释: 就像客服直接通过电子邮件回复问题,而不是转交纸质报告,让数据传递更快捷。
示例:
▼java复制代码@GetMapping("/user") @ResponseBody public User getUser() { return new User("张三", 30); }
@PathVariable
作用: 将 URL 路径中的模板变量绑定到方法参数上,常用于 RESTful URL。
通俗解释: 就像在文件柜上标注文件编号,系统通过这个编号找到对应文件。
示例:
▼java复制代码@GetMapping("/users/{id}") public User getUserById(@PathVariable("id") Long id) { return userService.findById(id); }
@Autowired
作用: 实现依赖注入,将容器中已管理的 Bean 自动注入到目标组件中。
通俗解释: 就像企业内部部门协同作战,系统自动把需要的资源送到对应的岗位,无需手动分配。
示例:
▼java复制代码@Service public class UserService { @Autowired private UserRepository userRepository; }
@Value
作用: 将外部化配置(如 properties 文件中的值)注入到 Bean 的字段中。
通俗解释: 类似于企业中动态读取最新的市场数据或配置信息,确保系统参数随时更新。
示例:
▼java复制代码@Component public class ConfigComponent { @Value("${server.port}") private int serverPort; }
@Bean
作用: 在配置类中标注方法,返回一个对象,并将该对象注册为 Spring 容器中的 Bean。
通俗解释: 就像企业标准化生产流程中的工序,每一步都明确指定如何生成和管理一个组件。
示例:
▼java复制代码@Configuration public class AppConfig { @Bean public UserService userService() { return new UserService(); } }
@Scope
作用: 指定 Bean 的作用域(例如 singleton、prototype 等),决定 Bean 在容器中的生命周期。
通俗解释: 就像企业中的资源分配,可以决定某个工具是全局共享(单例)还是每次使用都分配新的(原型)。
示例:
▼java复制代码@Component @Scope("prototype") public class PrototypeBean { // 每次注入时都会创建新的实例 }
总结
Spring Boot 启动与配置:
@SpringBootApplicationWeb 层控制器:
RestController、@RequestMapping、@GetMapping、@PostMapping、@PutMapping、@DeleteMapping参数与数据绑定:
@RequestParam、@RequestBody、@ResponseBody、@PathVariable依赖注入与配置:
@Autowired、@Value、@Bean、@Scope
@Configuration
作用: 声明一个配置类,该类中可定义多个 @Bean 方法,用于生成和配置 Spring 容器中的组件。
通俗解释: 就像企业的总体规划蓝图,规定了如何搭建和配置各个部门。
示例:
▼java复制代码@Configuration public class AppConfig { @Bean public MyService myService() { return new MyService(); } }
@Component
作用: 标识一个通用的 Spring 组件,自动被 Spring 扫描并注册到容器中。
通俗解释: 就像企业中各个部门的普通员工,只要符合条件就能加入公司,无需额外说明。
示例:
▼java复制代码@Component public class MyComponent { public void execute() { System.out.println("执行组件逻辑"); } }
@Repository
作用: 专用于数据访问层,标识 DAO 类,并提供数据库异常转换等功能。
通俗解释: 像企业中的档案管理员,专门负责与数据库(档案库)的交互和数据存取。
示例:
▼java复制代码@Repository public class UserRepository { public User findById(Long id) { // 数据访问逻辑 return new User(); } }
@Service
作用: 标识业务逻辑层组件,提供核心业务功能,便于业务逻辑的组织和管理。
通俗解释: 类似于企业中的核心业务部门,负责具体的业务操作和决策。
示例:
▼java复制代码@Service public class UserService { public void processUser() { System.out.println("处理用户业务逻辑"); } }
@ControllerAdvice
作用: 用于全局异常处理、数据绑定和增强,适用于所有控制器。
通俗解释: 就像企业设立的总客服中心,统一处理各部门(控制器)的问题和异常情况。
示例:
▼java复制代码@ControllerAdvice public class GlobalControllerAdvice { @ExceptionHandler(Exception.class) public ResponseEntity<String> handleException(Exception ex) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) .body("错误:" + ex.getMessage()); } }
@ConditionalOnMissingBean
作用: 条件化地创建 Bean,当容器中不存在指定类型的 Bean 时才生效。
通俗解释: 就像企业中只有在没有专门员工负责某项任务时,才会招聘新人来填补空缺。
示例:
▼java复制代码@Configuration public class ConditionalConfig { @Bean @ConditionalOnMissingBean(MyService.class) public MyService myService() { return new MyService(); } }
@ConditionalOnProperty
作用: 基于配置属性判断是否创建 Bean,只有当特定属性满足条件时才加载 Bean。
通俗解释: 类似于企业中只有在特定市场条件下才启动某个项目或部门。
示例:
▼java复制代码@Configuration public class PropertyConfig { @Bean @ConditionalOnProperty(name = "feature.enabled", havingValue = "true") public FeatureService featureService() { return new FeatureService(); } }
@ConditionalOnClass
作用: 当指定的类在类路径中存在时,条件生效,进而创建 Bean。
通俗解释: 就像企业在招聘时,会看市场上是否有某种技能人才,如果有则启动相应项目。
示例:
▼java复制代码@Configuration @ConditionalOnClass(name = "com.example.SomeLibrary") public class LibraryConfig { @Bean public LibraryService libraryService() { return new LibraryService(); } }
@ConditionalOnBean
作用: 当容器中存在某个 Bean 时,条件生效并创建新的 Bean。
通俗解释: 就像只有在团队中已有某位专家时,才会启动针对性项目,确保团队实力匹配。
示例:
▼java复制代码@Configuration public class BeanConfig { @Bean @ConditionalOnBean(name = "existingBean") public DependentService dependentService() { return new DependentService(); } }
@EnableConfigurationProperties
作用: 启用对 @ConfigurationProperties 注解的支持,将外部配置绑定到 Bean 上。
通俗解释: 类似于企业允许各部门读取外部政策和市场数据,自动调整内部配置。
示例:
▼java复制代码@Configuration @EnableConfigurationProperties(AppProperties.class) public class PropertiesConfig { }
@ConfigurationProperties
作用: 将外部配置(如 application.properties)映射到 Java 对象中,便于集中管理配置。
通俗解释: 就像企业将外部规定写入手册,各部门参照执行,确保所有人步调一致。
示例:
▼java复制代码@Component @ConfigurationProperties(prefix = "app") public class AppProperties { private String name; // getters and setters... }
@Import`
作用: 导入其他配置类,将多个配置类组合到一起。
通俗解释: 类似于企业将不同部门的计划整合到总方案中,共同制定总体策略。
示例:
▼java复制代码@Configuration @Import({DataSourceConfig.class, SecurityConfig.class}) public class MainConfig { }
@ImportResource
作用: 导入 XML 配置资源,与 Java 配置互补,用于加载传统的 Spring 配置文件。
通俗解释: 就像企业引入旧有的制度文档,与新的管理体系并存,保证平稳过渡。
示例:
▼java复制代码@Configuration @ImportResource("classpath:legacy-config.xml") public class XmlConfig { }
@Order
作用: 指定组件或切面的执行顺序,数字越小优先级越高。
通俗解释: 就像会议议程中按优先级排列讨论事项,确保最重要的先处理。
示例:
▼java复制代码@Component @Order(1) public class FirstProcessor implements Processor { // 处理逻辑 }
@Qualifier
作用: 在多个同类型 Bean 存在时,通过名称或标识区分注入具体的 Bean。
通俗解释: 类似于企业中明确指定哪个部门负责特定任务,避免职责不清。
示例:
▼java复制代码@Service public class OrderService { @Autowired @Qualifier("specialUserRepository") private UserRepository userRepository; }
@Lazy
作用: 启用 Bean 的懒加载,即在第一次使用时再初始化 Bean,而非启动时加载。
通俗解释: 就像企业中只有在需要时才启动某个部门,节约资源。
示例:
▼java复制代码@Component @Lazy public class HeavyResource { public HeavyResource() { System.out.println("HeavyResource 初始化"); } }
@RequestScope
作用: 将 Bean 的生命周期限定在一次 HTTP 请求内,每个请求都会生成新的实例。
通俗解释: 就像每次客户到访时,分配一位专属接待员,接待结束后该员工归还岗位。
示例:
▼java复制代码@Component @RequestScope public class RequestBean { // 每次请求生成新实例 }
@SessionScope
作用: 将 Bean 的生命周期限定在 HTTP 会话内,同一会话内共享同一实例。
通俗解释: 就像长期服务于某个 VIP 客户的专员,在客户会话期间一直陪同服务。
示例:
▼java复制代码@Component @SessionScope public class SessionBean { // 同一会话内共享 }
@ApplicationScope
作用: 将 Bean 的生命周期限定在整个应用的范围内,整个应用共享同一实例。
通俗解释: 就像企业内共享的公共资源,所有部门都可以使用。
示例:
▼java复制代码@Component @ApplicationScope public class AppWideBean { // 应用级共享实例 }
@EnableWebSocketMessageBroker
作用: 启用 WebSocket 消息代理,支持基于 STOMP 协议的实时通信。
通俗解释: 就像企业开通实时通讯频道,方便各部门之间即时交流和信息共享。
示例:
▼java复制代码@Configuration @EnableWebSocketMessageBroker public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry config) { config.enableSimpleBroker("/topic"); config.setApplicationDestinationPrefixes("/app"); } }
@MessageMapping
作用: 映射 WebSocket 消息到指定的处理方法,类似于 @RequestMapping,但用于 WebSocket 消息。
通俗解释: 就像企业内部即时通讯系统中,将不同的消息转发到相应部门处理。
示例:
▼java复制代码@Controller public class ChatController { @MessageMapping("/chat") @SendTo("/topic/messages") public String processMessage(String message) { return message; } }
@SendTo
作用: 指定 WebSocket 消息处理后,将消息发送到的目标地址。
通俗解释: 类似于指派消息的最终送达部门,确保信息送到正确的收件箱。
示例: 见上面的 @MessageMapping 示例。
@CrossOrigin
作用: 允许跨域请求,支持从不同域名访问控制器或方法。
通俗解释: 就像企业对外开放部分服务窗口,允许外部合作伙伴在规定条件下访问。
示例:
▼java复制代码@RestController @CrossOrigin(origins = "http://example.com") public class CrossOriginController { @GetMapping("/data") public String getData() { return "跨域数据"; } }
@Async
作用: 标记方法异步执行,使其在独立线程中运行,不阻塞调用线程。
通俗解释: 就像企业中安排后勤部门并行处理任务,不影响主流程。
示例:
▼java复制代码@Service public class AsyncService { @Async public void asyncTask() { System.out.println("异步任务执行中"); } }
@EnableAsync
作用: 启用 Spring 的异步方法执行功能。
通俗解释: 类似于在企业中建立一个并行处理中心,让任务可以同时进行。
示例:
▼java复制代码@Configuration @EnableAsync public class AsyncConfig { }
@EnableScheduling
作用: 启用定时任务调度功能,让 @Scheduled 注解生效。
通俗解释: 就像企业制定固定时间表,自动执行例行任务。
示例:
▼java复制代码@Configuration @EnableScheduling public class SchedulingConfig { }
@EventListener
作用: 标记方法为事件监听器,处理应用中发布的事件。
通俗解释: 就像企业中专门负责监听和响应内部公告的部门,及时做出反应。
示例:
▼java复制代码@Component public class MyEventListener { @EventListener public void handleEvent(Object event) { System.out.println("收到事件:" + event); } }
@CacheConfig
作用: 在类级别定义缓存的共同配置,如缓存名称,便于统一管理。
通俗解释: 类似于为一个部门统一制定缓存政策,所有方法默认使用同一缓存配置。
示例:
▼java复制代码@CacheConfig(cacheNames = "users") @Service public class UserService { // 缓存方法可直接使用 @Cacheable 等,无需重复配置缓存名称 }
@Lookup
作用: 实现方法注入,允许在运行时动态获取 Bean,绕过单例限制。
通俗解释: 就像临时查找最新版本的工具,确保使用的是最新资源而非老旧拷贝。
示例:
▼java复制代码@Component public abstract class CommandManager { public void process() { MyCommand command = getCommand(); command.execute(); } @Lookup protected abstract MyCommand getCommand(); }
@Conditional
作用: 通用条件注解,用于根据自定义条件决定 Bean 是否创建。
通俗解释: 类似于企业根据市场环境决定是否启动某个项目的规则。
示例:
▼java复制代码@Configuration public class ConditionalConfig { @Bean @Conditional(MyCondition.class) public SpecialService specialService() { return new SpecialService(); } }
@Profile
作用: 指定 Bean 在特定环境(profile)下加载,例如 dev、test、prod 等。
通俗解释: 就像企业中针对不同市场环境采取不同策略,确保系统在各个阶段都符合需求。
示例:
▼java复制代码@Component @Profile("dev") public class DevOnlyComponent { // 仅在开发环境加载 }
@Validated
作用: 启用对 Bean 参数的验证,常与 JSR-303 验证框架结合使用。
通俗解释: 就像企业对每份报告进行质量检查,确保数据和流程都符合标准。
示例:
▼java复制代码@RestController @Validated public class ValidationController { @PostMapping("/validate") public String validate(@Valid @RequestBody User user) { return "验证成功"; } }
@SpringBootConfiguration
作用: 标识一个 Spring Boot 配置类,功能与 @Configuration 类似,通常在主应用类中使用。
通俗解释: 就像企业总部的核心规划文件,规定了整个系统的基础配置和构建方式。
示例:
▼java复制代码@SpringBootConfiguration public class BootConfig { // 核心配置 }
