SpringBoot 注解最全详解,建议收藏!
mhr18 2024-12-14 11:16 18 浏览 0 评论
01、背景介绍
基于 SpringBoot 平台开发的项目数不胜数,与常规的基于Spring开发的项目最大的不同之处,SpringBoot 里面提供了大量的注解用于快速开发,而且非常简单,基本可以做到开箱即用!
那 SpringBoot 为开发者提供了多少注解呢?我们该如何使用?
针对此问题,小编特意对其进行了一番整理,内容如下,个人感觉还是比较清晰的,今天我们就一起来整一整每个注解的含义和用法,以免踩坑!
02、注解总结
2.1、SpringMVC 相关注解
- @Controller
通常用于修饰controller层的组件,由控制器负责将用户发来的URL请求转发到对应的服务接口,通常还需要配合注解@RequestMapping使用。
- @RequestMapping
提供路由信息,负责URL到Controller中具体函数的映射,当用于方法上时,可以指定请求协议,比如GET、POST、PUT、DELETE等等。
- @RequestBody
表示请求体的Content-Type必须为application/json格式的数据,接收到数据之后会自动将数据绑定到Java对象上去
- @ResponseBody
表示该方法的返回结果直接写入HTTP response body中,返回数据的格式为application/json
比如,请求参数为json格式,返回参数也为json格式,示例代码如下:
/**
* 登录服务
*/
@Controller
@RequestMapping("api")
public class LoginController {
/**
* 登录请求,post请求协议,请求参数数据格式为json
* @param request
*/
@RequestMapping(value = "login", method = RequestMethod.POST)
@ResponseBody
public ResponseEntity login(@RequestBody UserLoginDTO request){
//...业务处理
return new ResponseEntity(HttpStatus.OK);
}
}
- @RestController
和@Controller一样,用于标注控制层组件,不同的地方在于:它是@ResponseBody和@Controller的合集,也就是说,在当@RestController用在类上时,表示当前类里面所有对外暴露的接口方法,返回数据的格式都为application/json,示范代码如下:
@RestController
@RequestMapping("api")
public class LoginController {
/**
* 登录请求,post请求协议,请求参数数据格式为json
* @param request
*/
@RequestMapping(value = "login", method = RequestMethod.POST)
public ResponseEntity login(@RequestBody UserLoginDTO request){
//...业务处理
return new ResponseEntity(HttpStatus.OK);
}
}
- @RequestParam
用于接收请求参数为表单类型的数据,通常用在方法的参数前面,示范代码如下:
/**
* 登录请求,post请求协议,请求参数数据格式为表单
*/
@RequestMapping(value = "login", method = RequestMethod.POST)
@ResponseBody
public ResponseEntity login(@RequestParam(value = "userName",required = true) String userName,
@RequestParam(value = "userPwd",required = true) String userPwd){
//...业务处理
return new ResponseEntity(HttpStatus.OK);
}
- @PathVariable
用于获取请求路径中的参数,通常用于restful风格的api上,示范代码如下:
/**
* restful风格的参数请求
* @param id
*/
@RequestMapping(value = "queryProduct/{id}", method = RequestMethod.POST)
@ResponseBody
public ResponseEntity queryProduct(@PathVariable("id") String id){
//...业务处理
return new ResponseEntity(HttpStatus.OK);
}
- @GetMapping
除了@RequestMapping可以指定请求方式之外,还有一些其他的注解,可以用于标注接口路径请求,比如GetMapping用在方法上时,表示只支持get请求方法,等价于@RequestMapping(value="/get",method=RequestMethod.GET)
@GetMapping("get")
public ResponseEntity get(){
return new ResponseEntity(HttpStatus.OK);
}
- @PostMapping
用在方法上,表示只支持post方式的请求。
@PostMapping("post")
public ResponseEntity post(){
return new ResponseEntity(HttpStatus.OK);
}
- @PutMapping
用在方法上,表示只支持put方式的请求,通常表示更新某些资源的意思
@PutMapping("put")
public ResponseEntity put(){
return new ResponseEntity(HttpStatus.OK);
}
- @DeleteMapping
用在方法上,表示只支持delete方式的请求,通常表示删除某些资源的意思
@DeleteMapping("delete")
public ResponseEntity delete(){
return new ResponseEntity(HttpStatus.OK);
}
2.2、bean 相关注解
- @Service
通常用于修饰service层的组件,声明一个对象,会将类对象实例化并注入到bean容器里面
@Service
public class DeptService {
//具体的方法
}
- @Component
泛指组件,当组件不好归类的时候,可以使用这个注解进行标注,功能类似于于@Service
@Component
public class DeptService {
//具体的方法
}
- @Repository
通常用于修饰dao层的组件,
@Repository注解属于Spring里面最先引入的一批注解,它用于将数据访问层 (DAO层 ) 的类标识为Spring Bean,具体只需将该注解标注在 DAO类上即可,示例代码如下:
@Repository
public interface RoleRepository extends JpaRepository<Role,Long> {
//具体的方法
}
为什么现在使用的很少呢?
主要是因为当我们配置服务启动自动扫描dao层包时,Spring会自动帮我们创建一个实现类,然后注入到bean容器里面。当某些类无法被扫描到时,我们可以显式的在数据持久类上标注@Repository注解,Spring会自动帮我们声明对象。
- @Bean
相当于 xml 中配置 Bean,意思是产生一个 bean 对象,并交给spring管理,示例代码如下:
@Configuration
public class AppConfig {
//相当于 xml 中配置 Bean
@Bean
public Uploader initFileUploader() {
return new FileUploader();
}
}
- @Autowired
自动导入依赖的bean对象,默认时按照byType方式导入对象,而且导入的对象必须存在,当需要导入的对象并不存在时,我们可以通过配置required = false来关闭强制验证。
@Autowired
private DeptService deptService;
- @Resource
也是自动导入依赖的bean对象,由JDK提供,默认是按照byName方式导入依赖的对象;而@Autowired默认时按照byType方式导入对象,当然@Resource还可以配置成通过byType方式导入对象。
/**
* 通过名称导入(默认通过名称导入依赖对象)
*/
@Resource(name = "deptService")
private DeptService deptService;
/**
* 通过类型导入
*/
@Resource(type = RoleRepository.class)
private DeptService deptService;
- @Qualifier
当有多个同一类型的bean时,使用@Autowired导入会报错,提示当前对象并不是唯一,Spring不知道导入哪个依赖,这个时候,我们可以使用@Qualifier进行更细粒度的控制,选择其中一个候选者,一般于@Autowired搭配使用,示例如下:
@Autowired
@Qualifier("deptService")
private DeptService deptService;
- @Scope
用于生命一个spring bean的作用域,作用的范围一共有以下几种:
- singleton:唯一 bean 实例,Spring 中的 bean 默认都是单例的。
- prototype:每次请求都会创建一个新的 bean 实例,对象多例。
- request:每一次 HTTP 请求都会产生一个新的 bean,该 bean 仅在当前 HTTP request 内有效。
- session:每一次 HTTP 请求都会产生一个新的 bean,该 bean 仅在当前 HTTP session 内有效。
/**
* 单例对象
*/
@RestController
@Scope("singleton")
public class HelloController {
}
2.3、JPA 相关注解
- @Entity和@Table
表明这是一个实体类,这两个注解一般一块使用,但是如果表名和实体类名相同的话,@Table可以省略。
- @Id
表示该属性字段对应数据库表中的主键字段。
- @Column
表示该属性字段对应的数据库表中的列名,如果字段名与列名相同,则可以省略。
- @GeneratedValue
表示主键的生成策略,有四个选项,分别如下:
- AUTO:表示由程序控制,是默认选项 ,不设置就是这个
- IDENTITY:表示由数据库生成,采用数据库自增长,Oracle 不支持这种方式
- SEQUENCE:表示通过数据库的序列生成主键ID,MYSQL 不支持
- Table:表示由特定的数据库产生主键,该方式有利于数据库的移植
- @SequenceGeneretor
用来定义一个生成主键的序列,它需要与@GeneratedValue联合使用才有效,以TB_ROLE表为例,对应的注解配置如下:
@Entity
@Table(name = "TB_ROLE")
@SequenceGenerator(name = "id_seq", sequenceName = "seq_repair",allocationSize = 1)
public class Role implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键ID,采用【id_seq】序列函数自增长
*/
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "id_seq")
private Long id;
/* 角色名称
*/
@Column(nullable = false)
private String roleName;
/**
* 角色类型
*/
@Column(nullable = false)
private String roleType;
}
- @Transient
表示该属性并非与数据库表的字段进行映射,ORM 框架会将忽略该属性。
/**
* 忽略该属性
*/
@Column(nullable = false)
@Transient
private String lastTime;
- @Basic(fetch=FetchType.LAZY)
用在某些属性上,可以实现懒加载的效果,也就是当用到这个字段的时候,才会装载这个属性,如果配置成fetch=FetchType.EAGER,表示即时加载,也是默认的加载方式!
/**
* 延迟加载该属性
*/
@Column(nullable = false)
@Basic(fetch = FetchType.LAZY)
private String roleType;
- @JoinColumn
用于标注表与表之间关系的字段,通常与@OneToOne、@OneToMany搭配使用,例如如下
@Entity
@Table(name = "tb_login_log")
public class LoginLog implements Serializable {
/**
* 查询登录的用户信息
*/
@OneToOne
@JoinColumn(name = "user_id")
private User user;
//...get、set
}
- @OneToOne、@OneToMany和@ManyToOne
这三个注解,相当于hibernate配置文件中的一对一,一对多,多对一配置,比如下面的客户地址表,通过客户 ID,实现客户信息的查询。
@Entity
@Table(name="address")
public class AddressEO implements java.io.Serializable {
@ManyToOne(cascade = { CascadeType.ALL })
@JoinColumn(name="customer_id")
private CustomerEO customer;
//...get、set
}
2.4、配置相关注解
- @Configuration
表示声明一个 Java 形式的配置类,Spring Boot 提倡基于 Java 的配置,相当于你之前在 xml 中配置 bean,比如声明一个配置类AppConfig,然后初始化一个Uploader对象。
@Configuration
public class AppConfig {
@Bean
public Uploader initOSSUploader() {
return new OSSUploader();
}
}
- @EnableAutoConfiguration
@EnableAutoConfiguration可以帮助SpringBoot应用将所有符合条件的@Configuration配置类,全部都加载到当前SpringBoot里,并创建对应配置类的Bean,并把该Bean实体交给IoC容器进行管理。
某些场景下,如果我们想要避开某些配置类的扫描(包括避开一些第三方jar包下面的配置,可以这样处理。
@Configuration
@EnableAutoConfiguration(exclude = { org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class
})
public class AppConfig {
//具有业务方法
}
- @ComponentScan
标注哪些路径下的类需要被Spring扫描,用于自动发现和装配一些Bean对象,默认配置是扫描当前文件夹下和子目录下的所有类,如果我们想指定扫描某些包路径,可以这样处理。
@ComponentScan(basePackages = {"com.xxx.a", "com.xxx.b", "com.xxx.c"})
- @SpringBootApplication
等价于使用@Configuration、@EnableAutoConfiguration、@ComponentScan这三个注解,通常用于全局启动类上,示例如下:
@SpringBootApplication
public class PropertyApplication {
public static void main(String[] args) {
SpringApplication.run(PropertyApplication.class, args);
}
}
把@SpringBootApplication换成@Configuration、@EnableAutoConfiguration、@ComponentScan这三个注解,一样可以启动成功,@SpringBootApplication只是将这三个注解进行了简化!
- @EnableTransactionManagement
表示开启事务支持,等同于 xml 配置方式的<tx:annotation-driven />
@SpringBootApplication
@EnableTransactionManagement`
public class PropertyApplication {
public static void main(String[] args) {
SpringApplication.run(PropertyApplication.class, args);
}
}
- @Conditional
从 Spring4 开始,可以通过@Conditional注解实现按条件装载bean对象,目前 Spring Boot 源码中大量扩展了@Condition注解,用于实现智能的自动化配置,满足各种使用场景。下面我给大家列举几个常用的注解:
- @ConditionalOnBean:当某个特定的Bean存在时,配置生效
- @ConditionalOnMissingBean:当某个特定的Bean不存在时,配置生效
- @ConditionalOnClass:当Classpath里存在指定的类,配置生效
- @ConditionalOnMissingClass:当Classpath里不存在指定的类,配置生效
- @ConditionalOnExpression:当给定的SpEL表达式计算结果为true,配置生效
- @ConditionalOnProperty:当指定的配置属性有一个明确的值并匹配,配置生效
具体的应用案例如下:
@Configuration
public class ConditionalConfig {
/**
* 当AppConfig对象存在时,创建一个A对象
* @return
*/
@ConditionalOnBean(AppConfig.class)
@Bean
public A createA(){
return new A();
}
/**
* 当AppConfig对象不存在时,创建一个B对象
* @return
*/
@ConditionalOnMissingBean(AppConfig.class)
@Bean
public B createB(){
return new B();
}
/**
* 当KafkaTemplate类存在时,创建一个C对象
* @return
*/
@ConditionalOnClass(KafkaTemplate.class)
@Bean
public C createC(){
return new C();
}
/**
* 当KafkaTemplate类不存在时,创建一个D对象
* @return
*/
@ConditionalOnMissingClass(KafkaTemplate.class)
@Bean
public D createD(){
return new D();
}
/**
* 当enableConfig的配置为true,创建一个E对象
* @return
*/
@ConditionalOnExpression("${enableConfig:false}")
@Bean
public E createE(){
return new E();
}
/**
* 当filter.loginFilter的配置为true,创建一个F对象
* @return
*/
@ConditionalOnProperty(prefix = "filter",name = "loginFilter",havingValue = "true")
@Bean
public F createF(){
return new F();
}
}
- @value
可以在任意 Spring 管理的 Bean 中通过这个注解获取任何来源配置的属性值,比如你在application.properties文件里,定义了一个参数变量!
config.name=zhangsan
在任意的bean容器里面,可以通过@Value注解注入参数,获取参数变量值。
@RestController
public class HelloController {
@Value("${config.name}")
private String config;
@GetMapping("config")
public String config(){
return JSON.toJSONString(config);
}
}
- @ConfigurationProperties
上面@Value在每个类中获取属性配置值的做法,其实是不推荐的。
一般在企业项目开发中,不会使用那么杂乱无章的写法而且维护也麻烦,通常会一次性读取一个 Java 配置类,然后在需要使用的地方直接引用这个类就可以多次访问了,方便维护,示例如下:
首先,在application.properties文件里定义好参数变量。
config.name=demo_1
config.value=demo_value_1
然后,创建一个 Java 配置类,将参数变量注入即可!
@Component
@ConfigurationProperties(prefix = "config")
public class Config {
public String name;
public String value;
//...get、set
}
最后,在需要使用的地方,通过ioc注入Config对象即可!
- @PropertySource
这个注解是用来读取我们自定义的配置文件的,比如导入test.properties和bussiness.properties两个配置文件,用法如下:
@SpringBootApplication
@PropertySource(value = {"test.properties","bussiness.properties"})
public class PropertyApplication {
public static void main(String[] args) {
SpringApplication.run(PropertyApplication.class, args);
}
}
- @ImportResource
用来加载 xml 配置文件,比如导入自定义的aaa.xml文件,用法如下:
@ImportResource(locations = "classpath:aaa.xml")
@SpringBootApplication
public class PropertyApplication {
public static void main(String[] args) {
SpringApplication.run(PropertyApplication.class, args);
}
}
2.5、异常处理相关注解
- @ControllerAdvice和@ExceptionHandler
通常组合使用,用于处理全局异常,示例代码如下:
@ControllerAdvice
@Configuration
@Slf4j
public class GlobalExceptionConfig {
private static final Integer GLOBAL_ERROR_CODE = 500;
@ExceptionHandler(value = Exception.class)
@ResponseBody
public void exceptionHandler(HttpServletRequest request, HttpServletResponse response, Exception e) throws Exception {
log.error("【统一异常处理器】", e);
ResultMsg<Object> resultMsg = new ResultMsg<>();
resultMsg.setCode(GLOBAL_ERROR_CODE);
if (e instanceof CommonException) {
CommonException ex = (CommonException) e;
if(ex.getErrCode() != 0) {
resultMsg.setCode(ex.getErrCode());
}
resultMsg.setMsg(ex.getErrMsg());
}else {
resultMsg.setMsg(CommonErrorMsg.SYSTEM_ERROR.getMessage());
}
WebUtil.buildPrintWriter(response, resultMsg);
}
}
2.6、测试相关注解
- @ActiveProfiles
一般作用于测试类上, 用于声明生效的 Spring 配置文件,比如指定application-dev.properties配置文件。
- @RunWith和@SpringBootTest
一般作用于测试类上, 用于单元测试用,示例如下:
@ActiveProfiles("dev")
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestJunit {
@Test
public void executeTask() {
//测试...
}
}
03、小结
整个篇幅内容比较多,比较干,大家在看的过程中,也没有必要去记住,可以先收藏起来,等到需要用到的时候,再把它拿出来看看!
相关推荐
- 保持SSH隧道活跃:一个实用的Bash监控脚本
-
引言如果您正在使用AWSDocumentDB或任何位于堡垒主机后面的云托管服务等远程资源,您可能正在使用SSH隧道来安全地访问它们。虽然设置SSH隧道很简单,但保持其活跃状态并监控其状态可能会有些棘...
- 京东大佬问我,为什么说连接池是微服务的关键,你是如何理解的?
-
京东大佬问我,为什么说连接池是微服务的关键,你是如何理解的?我应该如何理解。首先,我需要回忆一下连接池和微服务的基本概念,然后思考它们在微服务架构中的作用和重要性。连接池,数据库连接池,用来管理数据库...
- OOM 血案:5 小时绝地求生,MAT+Arthas 终极排查指南
-
一、血案现场:线上服务突然暴毙2025年4月12日凌晨3点15分,服务突发大规模OOM,三个Pod在10分钟内连续崩溃,Prometheus告警显示JVM堆内存使用率...
- 记Tomcat优化方案
-
Tomcat服务吞吐量评估方案问题:评估方案在一台8核16G的linux服务器上,使用tomcat容器部署服务。在正常情况下如何评估这个tomcat服务可处理的连接数,即服务的吞吐量,请在正常情况下考...
- Java高级面试,常见数据结构的实现原理详细说明及面试总结
-
一、List接口实现类1.ArrayList底层结构:动态数组(Object[]数组)。核心原理:o动态扩容:初始容量为10(JDK1.8),当元素超过容量时,新容量为原容量的1.5倍(old...
- SpringBoot敏感配置项加密与解密实战
-
一、为什么要加密配置?先说说SpringBoot的配置加载机制。我们知道,SpringBoot支持多种配置加载方式,优先级从高到低大概是:命令行参数环境变量application-{profile}....
- 【面试题】nacos 配置管理类型-主配置、共享配置、扩展配置
-
nacos配置管理类型-主配置、共享配置、扩展配置Nacos的配置管理支持多种类型,其中共享配置及其扩展机制(如shared-configs和extension-configs)是微服...
- Spring Boot 的 RedisAutoConfiguration 配置:自动装配到自定义扩展
-
在SpringBoot开发中,Redis作为高性能缓存和分布式数据存储方案被广泛使用。而RedisAutoConfiguration作为SpringBoot自动装配体系的重要组成部分,能...
- Docker图像处理:扩展您的优化工作流程
-
随着应用程序的增长和图像处理需求的增加,传统的优化方法遇到了扩展瓶颈。内存限制、环境不一致和处理瓶颈将图像优化从一个已解决的问题变成了生产环境的噩梦。Docker改变了游戏规则。通过容器化图像处理工作...
- 掌握 Spring 框架这 10 个扩展点,让你的能力更上一层楼
-
当我们提到Spring时,或许首先映入脑海的是IOC(控制反转)和AOP(面向切面编程)。它们可以被视为Spring的基石。正是凭借其出色的设计,Spring才能在众多优秀框架中脱颖而出...
- 简简单单在线文件浏览的功能搞起来很头疼
-
您的系统支持在线预览文件吗?一个小小的问题,背后是无数程序员的爆肝研究,有人说了,我平时打开个文件不是很容易吗?其实不然。文件格式代表着软件行业的底层、高端产出,也代表着经久不衰的使用场景,也是我国底...
- 没硬盘、网盘也能看片自由!NAS一键部署MoonTV,随时随地爽看。
-
本内容来源于@什么值得买APP,观点仅代表作者本人|作者:羊刀仙有没有一个应用服务,能满足既没有足够预算购置硬盘,也不想依托网盘的朋友的家庭观影需求?之前我介绍过LibreTV,本篇再来看看另一个更...
- 阿里云ECS代理商:如何使用ECS部署Node.js应用?
-
Node.js作为一种高性能、事件驱动的JavaScript运行环境,广泛用于构建实时通信、微服务接口、后台管理系统等现代Web应用。而阿里云ECS服务器以高可用性、灵活配置、安全稳定等优势,为部署N...
- 阿里云数据库代理商:如何提高数据库的查询效率?
-
在现代企业应用中,数据库查询效率对整体系统性能的影响巨大。特别是随着数据量的不断增加,如何提升数据库查询的响应速度,成为了数据库优化的关键任务。阿里云提供了一系列工具和策略,帮助用户提升数据库的查询效...
- 阿里云代理商:阿里云G6ne实例如何承载1.4亿QPS?
-
一、阿里云G6ne实例概述1.1G6ne实例的背景与定位阿里云G6ne实例是基于阿里云自主研发的“飞天”架构设计的高性能云服务器实例,专为大规模、需要高IOPS和低延迟的业务场景设计。它采用了更强大的...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- oracle位图索引 (74)
- oracle批量插入数据 (65)
- oracle事务隔离级别 (59)
- oracle主从同步 (56)
- oracle 乐观锁 (53)
- redis 命令 (83)
- php redis (97)
- redis 存储 (67)
- redis 锁 (74)
- 启动 redis (73)
- redis 时间 (60)
- redis 删除 (69)
- redis内存 (64)
- redis并发 (53)
- redis 主从 (71)
- redis同步 (53)
- redis结构 (53)
- redis 订阅 (54)
- redis 登录 (62)
- redis 面试 (58)
- redis问题 (54)
- 阿里 redis (67)
- redis的缓存 (57)
- lua redis (59)
- redis 连接池 (64)