1.@SpringBootApplication

这里先单独拎出 @SpringBootApplication 注解说一下,虽然我们一般不会主动去使用它。

这个注解是 Spring Boot 项目的基石,创建 SpringBoot 项目之后会默认在主类加上。

@SpringBootApplicationpublic class SpringSecurityJwtGuideApplication {public static void main(java.lang.String[] args) { SpringApplication.run(SpringSecurityJwtGuideApplication.class, args); }}

我们可以把 @SpringBootApplication 看作是 @Configuration@EnableAutoConfiguration@ComponentScan 注解的集合。

package org.springframework.boot.autoconfigure;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {@Filter(type = FilterType.CUSTOM, classes =TypeExcludeFilter.class),@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {......
}package org.springframework.boot;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {}

根据 SpringBoot 官网,这三个注解的作用分别是:

  • @EnableAutoConfiguration :启用 SpringBoot 的自动配置机制
  • @ComponentScan : 扫描被 @Component ( @Service , @Controller )注解的 bean和扫描@Configuration标注的配置类,注解默认会扫描该类所在的包下所有的类。
  • @Configuration :允许在 Spring 上下文中注册额外的 bean 或导入其他配置类

2.Spring Bean相关

2.1@Autowired

自动导入对象到类中,被注入进的类同样要被 Spring 容器管理比如:Service 类注入到 Controller 类中。

@Service
public class UserService { ......}@RestController
@RequestMapping("/users")
public class UserController { @Autowired private UserService userService;......
}

2.2@Component,@Repository,@Service,@Controller

我们一般使用 @Autowired 注解让 Spring 容器帮我们自动装配 bean。要想把类标识成可用于@Autowired 注解自动装配的 bean 的类,可以采用以下注解实现:

  • @Component :通用的注解,可标注任意类为 Spring 组件。如果一个 Bean 不知道属于哪个层,可以使用 @Component 注解标注。
  • @Repository : 对应持久层即 Dao 层,主要用于数据库相关操作。
  • @Service : 对应服务层,主要涉及一些复杂的逻辑,需要用到 Dao 层。
  • @Controller : 对应 Spring MVC 控制层,主要用户接受用户请求并调用 Service 层返回数据给前端页面。

2.3@RestCotroller

@RestController 注解是 @Controller和 @ ResponseBody 的合集,表示这是个控制器 bean,并且是将函数的返回值直接填入 HTTP 响应体中,是 REST 风格的控制器。

现在都是前后端分离,项目中已经很久没有用过 @Controller 。

单独使用 @Controller 不加 @ResponseBody 的话一般使用在要返回一个视图的情况,这种情况属于比较传统的 Spring MVC 的应用,对应于前后端不分离的情况。 @Controller + @ResponseBody 返回JSON 或 XML 形式数据

2.4@Scope

声明 Spring Bean 的作用域,使用方法:

@Bean
@Scope("singleton")
public Person personSingleton() {return new Person();
}

四种常见的 Spring Bean 的作用域:

  • singleton : 唯一 bean 实例,Spring 中的 bean 默认都是单例的。
  • prototype : 每次请求都会创建一个新的 bean 实例。
  • request : 每一次 HTTP 请求都会产生一个新的 bean,该 bean 仅在当前 HTTP request 内有效。
  • session : 每一次 HTTP 请求都会产生一个新的 bean,该 bean 仅在当前 HTTP session 内有效。

2.5@Configuration

一般用来声明配置类,可以使用 @Component 注解替代,不过使用 Configuration 注解声明配置类更加语义化。

@Configuration
public class AppConfig {@Bean public TransferService transferService() {return new TransferServiceImpl(); } }

3.处理常见的HTTP请求类型

5 种常见的请求类型:

  • GET :请求从服务器获取特定资源。举个例子: GET /users (获取所有学生)
  • POST :在服务器上创建一个新的资源。举个例子: POST /users (创建学生)
  • PUT :更新服务器上的资源(客户端提供更新后的整个资源)。举个例子: PUT /users/12 (更新编号为 12 的学生)
  • DELETE :从服务器删除特定的资源。举个例子: DELETE /users/12 (删除编号为 12 的学生)
  • PATCH :更新服务器上的资源(客户端提供更改的属性,可以看做作是部分更新),使用的比较少,这里就不举例子了。

3.1GET请求

@GetMapping(“users”) 等价于 @RequestMapping(value="/users",method=RequestMethod.GET)

@GetMapping("/users")
public ResponseEntity<List<User>> getAllUsers() { return userRepository.findAll();
}

3.2POST请求

@PostMapping(“users”) 等价于
@RequestMapping(value="/users",method=RequestMethod.POST)
关于 @RequestBody 注解的使用,在下面的“前后端传值”这块会讲到。

@PostMapping("/users")
public ResponseEntity<User> createUser(@Valid @RequestBody UserCreateRequest userCreateRequest) { return userRespository.save(user);
}

3.3PUT请求

@PutMapping("/users/{userId}") 等价于
@RequestMapping(value="/users/{userId}",method=RequestMethod.PUT)

@PutMapping("/users/{userId}")
public ResponseEntity<User> updateUser(@PathVariable(value = "userId") Long userId, @Valid @RequestBody UserUpdateRequest userUpdateRequest) {.....
}

3.4DELETE请求

@DeleteMapping("/users/{userId}") 等价于
@RequestMapping(value="/users/{userId}",method=RequestMethod.DELETE)

@DeleteMapping("/users/{userId}")
public ResponseEntity deleteUser(@PathVariable(value = "userId") Long userId){...... }

3.5PATCH请求

一般实际项目中,我们都是 PUT 不够用了之后才用 PATCH 请求去更新数据。

@PatchMapping("/profile")
public ResponseEntity updateStudent(@RequestBody StudentUpdateRequest studentUpdateRequest) { studentRepository.updateDetail(studentUpdateRequest);return ResponseEntity.ok().build();
}

4.前后端传值

4.1@PathVariable和@RequestParam

@PathVariable 用于获取路径参数, @RequestParam 用于获取查询参数。
举个简单的例子:

@GetMapping("/klasses/{klassId}/teachers")
public List<Teacher> getKlassRelatedTeachers( @PathVariable("klassId") Long klassId, @RequestParam(value = "type", required = false) String type ) { ...
}

如果我们请求的 url 是: /klasses/{123456}/teachers?type=web
那么我们服务获取到的数据就是: klassId=123456,type=web 。

4.2@RequestBody

用于Request 请求(可能是 POST,PUT,DELETE,GET 请求)的 body 部分并且Content-Type 为application/json 格式的数据,接收到数据之后会自动将数据绑定到 Java 对象上去。系统会使用HttpMessageConverter 或者自定义的 HttpMessageConverter 将请求的 body 中的 json 字符串转换为 java 对象。

我用一个简单的例子来给演示一下基本使用!
我们有一个注册的接口:

@PostMapping("/sign-up")
public ResponseEntity signUp(@RequestBody @Valid UserRegisterRequest userRegisterRequest) { userService.save(userRegisterRequest);return ResponseEntity.ok().build();
}

UserRegisterRequest 对象:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserRegisterRequest { @NotBlank private String userName; @NotBlank private String password; @FullName @NotBlank private String fullName;
}

我们发送 post 请求到这个接口,并且 body 携带 JSON 数据:

{"userName":"coder","fullName":"shuangkou","password":"123456"}

这样我们的后端就可以直接把 json 格式的数据映射到我们的 UserRegisterRequest 类上。

  • 需要注意的是:一个请求方法只可以有一个 @RequestBody ,但是可以有多个 @RequestParam 和 @PathVariable 。 如果你的方法必须要用两个 @RequestBody 来接受数据的话,大概率是你的数据库设计或者系统设计出问题了!

5.读取配置信息

很多时候我们需要将一些常用的配置信息比如阿里云 oss、发送短信、微信认证的相关配置信息等等放到配置文件中。

下面我们来看一下 Spring 为我们提供了哪些方式帮助我们从配置文件中读取这些配置信息。

我们的数据源 application.yml 内容如下:

wuhan2020: 2020年初武汉爆发了新型冠状病毒,疫情严重,但是,我相信一切都会过去!武汉加油!中国 加油!
my-profile:name: Guide哥 email: koushuangbwcx@163.com
library:location: 湖北武汉加油中国加油books: -name: 天才基本法 -description: 二十二岁的林朝夕在父亲确诊阿尔茨海默病这天,得知自己暗恋多年的校园男神裴之 即将出国深造的消息——对方考取的学校,恰是父亲当年为她放弃的那所。 -name: 时间的秩序

5.1@Value

使用 @Value("${property}") 读取比较简单的配置信息:

@Value("${wuhan2020}")
String wuhan2020;

5.2@ConfigurationProperties

通过 @ConfigurationProperties 读取配置信息并与 bean 绑定。

@Component
@ConfigurationProperties(prefix = "library")
class LibraryProperties { @NotEmpty private String location;private List<Book> books; @Setter @Getter @ToString static class Book { String name; String description; } 省略getter/setter ......
}

你可以像使用普通的 Spring bean 一样,将其注入到类中使用。

5.3@PropertySource

@PropertySource 读取指定 properties 文件

@Component
@PropertySource("classpath:website.properties")
class WebSite { @Value("${url}") private String url; 省略getter/setter ......
}

6.参数校验

数据的校验的重要性就不用说了,即使在前端对数据进行校验的情况下,我们还是要对传入后端的数据再进行一遍校验,避免用户绕过浏览器直接通过一些 HTTP 工具直接向后端请求一些违法数据。

JSR(Java Specification Requests) 是一套 JavaBean 参数校验的标准,它定义了很多常用的校验注解,我们可以直接将这些注解加在我们 JavaBean 的属性上面,这样就可以在需要校验的时候进行校验
了,非常方便!

校验的时候我们实际用的是 Hibernate Validator 框架。Hibernate Validator 是 Hibernate 团队最初的数据校验框架,Hibernate Validator 4.x 是 Bean Validation 1.0(JSR 303)的参考实现,HibernateValidator 5.x 是 Bean Validation 1.1(JSR 349)的参考实现,目前最新版的Hibernate Validator 6.x是 Bean Validation 2.0(JSR 380)的参考实现。

SpringBoot 项目的 spring-boot-starter-web 依赖中已经有 hibernate-validator 包,不需要引用相关依赖。如下图所示(通过 idea 插件—Maven Helper 生成

需要注意的是: 所有的注解,推荐使用 JSR 注解,即 javax.validation.constraints ,而不 是 org.hibernate.validator.constraints

6.1一些常用字段验证的注解

  • @NotEmpty 被注释的字符串的不能为 null 也不能为空
  • @NotBlank 被注释的字符串非 null,并且必须包含一个非空白字符
  • @Null 被注释的元素必须为 null
  • @NotNull 被注释的元素必须不为 null
  • @AssertTrue 被注释的元素必须为 true
  • @AssertFalse 被注释的元素必须为 false
  • @Pattern(regex=,flag=) 被注释的元素必须符合指定的正则表达式
  • @Email 被注释的元素必须是 Email 格式。
  • @Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
  • @Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
  • @DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
  • @DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
  • @Size(max=, min=) 被注释的元素的大小必须在指定的范围内
  • @Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
  • @Past 被注释的元素必须是一个过去的日期
  • @Future 被注释的元素必须是一个将来的日期

6.2验证请求体(@RequestBody)

校验类参数

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {@NotNull(message = "classId 不能为空")private String classId;@Size(max = 33) @NotNull(message = "name 不能为空") private String name; @Pattern(regexp = "((^Man$|^Woman$|^UGM$))", message = "sex 值不在可选范围") @NotNull(message = "sex 不能为空") private String sex; @Email(message = "email 格式不正确") @NotNull(message = "email 不能为空") private String email;
}

我们需要验证的参数上加上了 @Valid 注解,如果验证失败,它将抛出MethodArgumentNotValidException 。

@RestController
@RequestMapping("/api")
public class PersonController { @PostMapping("/person") public ResponseEntity<Person> getPerson(@RequestBody @Valid Person person) { return ResponseEntity.ok().body(person);}}

6.3验证请求参数(@PathVariable和@RequestParameters)

校验方法参数

一定一定不要忘记在类上加上 Validated 注解了,这个参数可以告诉 Spring 去校验方法参数

@RequestMapping("/api")
@Validated
public class PersonController { @GetMapping("/person/{id}") public ResponseEntity<Integer> getPersonByID(@Valid @PathVariable("id") @Max(value = 5,message = "超过 id 的范围了") Integer id) { return ResponseEntity.ok().body(id);}}

7.全局处理相关

介绍一下我们 Spring 项目必备的全局处理 Controller 层异常。
相关注解:

  1. @ControllerAdvice :注解定义全局异常处理类
  2. @ExceptionHandler :注解声明异常处理方法如何使用呢?拿我们在第 5 节参数校验这块来举例子。如果方法参数不对的话就会抛出MethodArgumentNotValidException ,我们来处理这个异常。
@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler { /*** 请求参数异常处理 */ @ExceptionHandler(MethodArgumentNotValidException.class) public ResponseEntity<?> handleMethodArgumentNotValidException(MethodArgumentNotValidException ex, HttpServletRequest request) { ...... }
}

8.JPA相关

8.1创建表

@Entity 声明一个类对应一个数据库实体。
@Table 设置表明

@Entity
@Table(name = "role")
public class Role { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id;private String name; private String description; 省略getter/setter......
}

8.2创建主键

@Id :声明一个字段为主键。
使用 @Id 声明之后,我们还需要定义主键的生成策略。我们可以使用 @GeneratedValue 指定主键生成策略。

1.通过 @GeneratedValue 直接使用 JPA 内置提供的四种主键生成策略来指定主键生成策略。

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

JPA 使用枚举定义了 4 中常见的主键生成策略,如下:
枚举替代常量的一种用法

public enum GenerationType { /*** 使用一个特定的数据库表格来保存主键 * 持久化引擎通过关系数据库的一张特定的表格来生成主键, * */ TABLE,/***在某些数据库中,不支持主键自增长,比如Oracle、PostgreSQL其提供了一种叫做"序列 (sequence)"的机制生成主键 */ SEQUENCE,/*** 主键自增长 */ IDENTITY,/***把主键生成策略交给持久化引擎(persistence engine), *持久化引擎会根据数据库在以上三种主键生成 策略中选择其中一种 */ AUTO}

@GeneratedValue 注解默认使用的策略是 GenerationType.AUTO

public @interface GeneratedValue {GenerationType strategy() default AUTO;String generator() default "";
}

一般使用 MySQL 数据库的话,使用 GenerationType.IDENTITY 策略比较普遍一点(分布式系统的话需要另外考虑使用分布式 ID)。

2.通过 @GenericGenerator 声明一个主键策略,然后 @GeneratedValue 使用这个策略

@Id
@GeneratedValue(generator = "IdentityIdGenerator")
@GenericGenerator(name = "IdentityIdGenerator", strategy = "identity")
private Long id;

等价于:

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

jpa 提供的主键生成策略有如下几种:

8.3设置字段类型

@Column 声明字段。
示例:

设置属性 userName 对应的数据库字段名为 user_name,长度为 32,非空

@Column(name = "user_name", nullable = false, length=32)
private String userName;

设置字段类型并且加默认值,这个还是挺常用的。

@Column(columnDefinition = "tinyint(1) default 1")
private Boolean enabled;

8.4指定不持久化特定字段

8.5声明大字段

8.6创建枚举类型的字段

可以使用枚举类型的字段,不过枚举字段要用 @Enumerated 注解修饰。

8.7增加审计功能


8.8删除、修改数据

8.9关联关系

  • @OneToOne 声明一对一关系
  • @OneToMany 声明一对多关系
  • @ManyToOne 声明多对一关系
  • MangToMang 声明多对多关系

9.事务@Transaction

在要开启事务的方法上使用 @Transactional 注解即可!

@Transactional(rollbackFor = Exception.class)
public void save() { ......
}

我们知道 Exception 分为运行时异常 RuntimeException 和非运行时异常。在 @Transactional 注解中如果不配置 rollbackFor 属性,那么事物只会在遇到 RuntimeException 的时候才会回滚,加上rollbackFor=Exception.class ,可以让事物在遇到非运行时异常时也回滚。

@Transactional 注解一般用在可以作用在 类 或者 方法 上。

  • 作用于类:当把 @Transactional 注解放在类上时,表示所有该类的 public 方法都配置相同的事务属性信息。
  • 作用于方法:当类配置了 @Transactional ,方法也配置了 @Transactional ,方法的事务会覆盖类的事务配置信息

10.json数据处理

10.1过滤json数据

@JsonIgnoreProperties 作用在类上用于过滤掉特定字段不返回或者不解析。

//生成json时将userRoles属性过滤
@JsonIgnoreProperties({"userRoles"})
public class User { private String userName; private String fullName; private String password; @JsonIgnore private List<UserRole> userRoles = new ArrayList<>();}

@JsonIgnore 一般用于类的属性上,作用和上面的@JsonIgnoreProperties 一样。

public class User { private String userName; private String fullName; private String password; //生成json时将userRoles属性过滤 @JsonIgnore private List<UserRole> userRoles = new ArrayList<>();
}

10.2格式化json数据

@JsonFormat 一般用来格式化 json 数据。:
比如:

@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", timezone="GMT")
private Date date;

10.3扁平化对象

@Getter
@Setter
@ToString
public class Account { @JsonUnwrapped private Location location; @JsonUnwrappedprivate PersonInfo personInfo; @Getter @Setter @ToString public static class Location { private String provinceName;private String countyName;}@Getter @Setter @ToString public static class PersonInfo { private String userName; private String fullName; }}

未扁平化之前:

使用@JsonUnwrapped 扁平对象之后:

@Getter
@Setter
@ToString
public class Account { @JsonUnwrapped private Location location; @JsonUnwrapped private PersonInfo personInfo; ......
}

11.相关测试

@ActiveProfiles 一般作用于测试类上, 用于声明生效的 Spring 配置文件。

@SpringBootTest(webEnvironment = RANDOM_PORT)
@ActiveProfiles("test")
@Slf4j
public abstract class TestBase { ...... }

@Test 声明一个方法为测试方法
@Transactional 被声明的测试方法的数据会回滚,避免污染测试数据。
@WithMockUser Spring Security 提供的,用来模拟一个真实用户,并且可以赋予权限。

@Test
@Transactional
@WithMockUser(username = "user-id-18163138155", authorities = "ROLE_TEACHER") void should_import_student_success() throws Exception {......
}

Spring常见注解相关推荐

  1. Spring Aop 常见注解和执行顺序

    欢迎关注方志朋的博客,回复"666"获面试宝典 来源:juejin.cn/post/7062506923194581029 Spring 一开始最强大的就是 IOC / AOP 两 ...

  2. Spring Boot中常见注解诠释

    一:@Mapper和@MapperScan 1.@Mapper @Mapper 将接口交给Spring进行管理,为这个接口生成一个实现类,让别的类进行引用.不再写mapper映射文件. @Mapper ...

  3. 一次性搞懂Spring Boot 注解原理与自动装配原理,图文并茂,万字长文!

    原文:cnblogs.com/jing99/p/11504113.html 首先,先看SpringBoot的主配置类: @SpringBootApplication public class Star ...

  4. 10000 字讲清楚 Spring Boot 注解原理

    今日推荐 借助Redis锁,完美解决高并发秒杀问题还在直接用JWT做鉴权?JJWT真香Spring Boot 操作 Redis 的各种实现Fluent Mybatis 牛逼!Nginx 常用配置清单这 ...

  5. Spring 之注解事务 @Transactional

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. 先让我们看代码吧! 以下代码为在"Spring3事务管理--基于tx/aop命名空间的配置 ...

  6. 【Spring】Spring 深入理解注解及spring对注解的增强

    1.概述 深入理解注解及spring对注解的增强 2. 什么是注解? 代码中注释大家都熟悉吧,注释是给开发者看的,可以提升代码的可读性和可维护性,但是对于java编译器和虚拟机来说是没有意义的,编译之 ...

  7. @enableautoconfiguration注解作用_如何让代码变“高级”-Spring组合注解提升代码维度(这么有趣)...

    [如何让代码变"高级"]-Spring组合注解提升代码维度 "致"高级"工程师(BUG工程师) 一颗折腾的心:heartpulse: 原创不易,点个赞 ...

  8. ssm与springboot常见注解

    MyBatis中常见的注解 @Insert:设置添加数据的SQL语句注解,标注在数据访问层的方法上 @Insert("insert into student_tab values(null, ...

  9. Spring Boot 注解原理,自动装配原理,图文并茂,万字长文!

    首先,先看SpringBoot的主配置类: @SpringBootApplication public class StartEurekaApplication {public static void ...

最新文章

  1. 关于 vmware虚拟机的一些问题及解决办法备忘
  2. 分享一个VS2013代码窗口一闪而过的解决方案。
  3. string查找字符(串)
  4. 基于KELI5 新建一个STM32 project流程
  5. 设置 cmd 窗口默认为快速编辑(quickedit)
  6. android开发找不到模拟器(PANIC: Could not open:)解决办法
  7. 程序员代码规范——马化腾、刘强东写的代码,你见过吗
  8. 好看的头像太多了,全部拿住!
  9. 电阻、电容及电感的高频等效电路及特性曲线
  10. 汽车车身钣金—车身连接方式
  11. 神秘鸭,让语音操作电脑不再神秘 小爱同学
  12. oracle会计科目明细请求,Oracle EBS R12财务月结基础
  13. 【推荐系统】HIN异构信息网络(Hetegeneous Information Network)
  14. Win11dns异常怎么修复?Win11修复dns异常的三种方法
  15. SAP开发框架系列之 自定义批次管理
  16. 【独家提供】cs1.5版CSOL人物 女性角色模型下载
  17. 通过OpenCV对视频进行绿幕抠图
  18. python miio 连接小米网关_时隔五年小米门窗传感器重磅升级开合光线检测二合一 仅49元...
  19. 安卓APP源码和报告——音乐播放器
  20. SIKI学院:MySQL数据库从零到精通:十五:课时 19 : 18-关于MySQL数据库中的数据类型和帮助文档

热门文章

  1. 固定div的位置——不随窗口大小改变为改变位置
  2. 2017-10-5模拟赛T2 小Z爱排序(sorting.*)
  3. lintcode480- Binary Tree Paths- easy
  4. SpringBoot集成jsp(附源码)+遇到的坑
  5. 斯坦福iOS7公开课4-6笔记及演示Demo
  6. GridView绑定时通过RowDataBound事件获取数据源列值
  7. 25个国外优秀电子商务网站设计案例
  8. Visual Studio 2019连接自动的Sql Server开发版数据库(C#语言)
  9. PXI和CompactPCI的区别比较
  10. windows php扩展下载,有没有专门下载 Windows 下的 PHP 扩展的网站?