成都比较好的网站制作公司,厦门有设计网站的吗,wordpress页面加载时间,中国的网站做欧美风接近8000字的Spring/Spring常用注解总结#xff01;安排
为什么要写这篇文章#xff1f;
最近看到网上有一篇关于 SpringBoot 常用注解的文章被转载的比较多#xff0c;我看了文章内容之后属实觉得质量有点低#xff0c;并且有点会误导没有太多实际使用经验的人#xff…接近8000字的Spring/Spring常用注解总结安排
为什么要写这篇文章
最近看到网上有一篇关于 SpringBoot 常用注解的文章被转载的比较多我看了文章内容之后属实觉得质量有点低并且有点会误导没有太多实际使用经验的人这些人又占据了大多数。所以自己索性花了大概 两天时间简单总结一下了。
因为我个人的能力和精力有限如果有任何不对或者需要完善的地方请帮忙指出Guide 哥感激不尽
1. SpringBootApplication
这里先单独拎出SpringBootApplication 注解说一下虽然我们一般不会主动去使用它。
Guide 哥这个注解是 Spring Boot 项目的基石创建 SpringBoot 项目之后会默认在主类加上。
复制代码SpringBootApplication
public 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允许在 Spring 上下文中注册额外的 bean 或导入其他配置类
2. Spring Bean 相关
2.1. Autowired
自动导入对象到类中被注入进的类同样要被 Spring 容器管理比如Service 类注入到 Controller 类中。
复制代码Service
public class UserService {......
}RestController
RequestMapping(/users)
public class UserController {Autowiredprivate 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. RestController
RestController注解是Controller和ResponseBody的合集,表示这是个控制器 bean,并且是将函数的返回值直 接填入 HTTP 响应体中,是 REST 风格的控制器。
Guide 哥现在都是前后端分离说实话我已经很久没有用过Controller。如果你的项目太老了的话就当我没说。
单独使用 Controller 不加 ResponseBody的话一般使用在要返回一个视图的情况这种情况属于比较传统的 Spring MVC 的应用对应于前后端不分离的情况。Controller ResponseBody 返回 JSON 或 XML 形式数据
关于RestController 和 Controller的对比请看这篇文章RestController vs Controller。
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 {Beanpublic 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.1. GET 请求
GetMapping(users) 等价于RequestMapping(value/users,methodRequestMethod.GET)
复制代码GetMapping(/users)
public ResponseEntityListUser getAllUsers() {return userRepository.findAll();
}3.2. POST 请求
PostMapping(users) 等价于RequestMapping(value/users,methodRequestMethod.POST)关于RequestBody注解的使用在下面的“前后端传值”这块会讲到。
复制代码PostMapping(/users)
public ResponseEntityUser createUser(Valid RequestBody UserCreateRequest userCreateRequest) {return userRespository.save(user);
}3.3. PUT 请求
PutMapping(/users/{userId}) 等价于RequestMapping(value/users/{userId},methodRequestMethod.PUT)
复制代码PutMapping(/users/{userId})
public ResponseEntityUser updateUser(PathVariable(value userId) Long userId,Valid RequestBody UserUpdateRequest userUpdateRequest) {......
}3.4. DELETE 请求
DeleteMapping(/users/{userId})等价于RequestMapping(value/users/{userId},methodRequestMethod.DELETE)
复制代码DeleteMapping(/users/{userId})
public ResponseEntity deleteUser(PathVariable(value userId) Long userId){......
}3.5. PATCH 请求
一般实际项目中我们都是 PUT 不够用了之后才用 PATCH 请求去更新数据。
复制代码 PatchMapping(/profile)public ResponseEntity updateStudent(RequestBody StudentUpdateRequest studentUpdateRequest) {studentRepository.updateDetail(studentUpdateRequest);return ResponseEntity.ok().build();}4. 前后端传值
掌握前后端传值的正确姿势是你开始 CRUD 的第一步
4.1. PathVariable 和 RequestParam
PathVariable用于获取路径参数RequestParam用于获取查询参数。
举个简单的例子
复制代码GetMapping(/klasses/{klassId}/teachers)
public ListTeacher getKlassRelatedTeachers(PathVariable(klassId) Long klassId,RequestParam(value type, required false) String type ) {
...
}如果我们请求的 url 是/klasses/{123456}/teachers?typeweb
那么我们服务获取到的数据就是klassId123456,typeweb。
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 {NotBlankprivate String userName;NotBlankprivate String password;FullNameNotBlankprivate 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: koushuangbwcx163.comlibrary:location: 湖北武汉加油中国加油books:- name: 天才基本法description: 二十二岁的林朝夕在父亲确诊阿尔茨海默病这天得知自己暗恋多年的校园男神裴之即将出国深造的消息——对方考取的学校恰是父亲当年为她放弃的那所。- name: 时间的秩序description: 为什么我们记得过去而非未来时间“流逝”意味着什么是我们存在于时间之内还是时间存在于我们之中卡洛·罗韦利用诗意的文字邀请我们思考这一亘古难题——时间的本质。- name: 了不起的我description: 如何养成一个新习惯如何让心智变得更成熟如何拥有高质量的关系 如何走出人生的艰难时刻5.1. value(常用)
使用 Value(${property}) 读取比较简单的配置信息
复制代码Value(${wuhan2020})
String wuhan2020;5.2. ConfigurationProperties(常用)
通过ConfigurationProperties读取配置信息并与 bean 绑定。
复制代码Component
ConfigurationProperties(prefix library)
class LibraryProperties {NotEmptyprivate String location;private ListBook books;SetterGetterToStringstatic 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......
}更多内容请查看我的这篇文章《10 分钟搞定 SpringBoot 如何优雅读取配置文件》 。
6. 参数校验
数据的校验的重要性就不用说了即使在前端对数据进行校验的情况下我们还是要对传入后端的数据再进行一遍校验避免用户绕过浏览器直接通过一些 HTTP 工具直接向后端请求一些违法数据。
JSR(Java Specification Requests 是一套 JavaBean 参数校验的标准它定义了很多常用的校验注解我们可以直接将这些注解加在我们 JavaBean 的属性上面这样就可以在需要校验的时候进行校验了非常方便
校验的时候我们实际用的是 Hibernate Validator 框架。Hibernate Validator 是 Hibernate 团队最初的数据校验框架Hibernate Validator 4.x 是 Bean Validation 1.0JSR 303的参考实现Hibernate Validator 5.x 是 Bean Validation 1.1JSR 349的参考实现目前最新版的 Hibernate Validator 6.x 是 Bean Validation 2.0JSR 380的参考实现。
SpringBoot 项目的 spring-boot-starter-web 依赖中已经有 hibernate-validator 包不需要引用相关依赖。如下图所示通过 idea 插件—Maven Helper 生成 非 SpringBoot 项目需要自行引入相关依赖包这里不多做讲解具体可以查看我的这篇文章《如何在 Spring/Spring Boot 中做参数校验你需要了解的都在这里》。 需要注意的是 所有的注解推荐使用 JSR 注解即javax.validation.constraints而不是org.hibernate.validator.constraints
6.1. 一些常用的字段验证的注解
NotEmpty 被注释的字符串的不能为 null 也不能为空NotBlank 被注释的字符串非 null并且必须包含一个非空白字符Null 被注释的元素必须为 nullNotNull 被注释的元素必须不为 nullAssertTrue 被注释的元素必须为 trueAssertFalse 被注释的元素必须为 falsePattern(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 ResponseEntityPerson getPerson(RequestBody Valid Person person) {return ResponseEntity.ok().body(person);}
}6.3. 验证请求参数(Path Variables 和 Request Parameters)
一定一定不要忘记在类上加上 Validated 注解了这个参数可以告诉 Spring 去校验方法参数。
复制代码RestController
RequestMapping(/api)
Validated
public class PersonController {GetMapping(/person/{id})public ResponseEntityInteger getPersonByID(Valid PathVariable(id) Max(value 5,message 超过 id 的范围了) Integer id) {return ResponseEntity.ok().body(id);}
}更多关于如何在 Spring 项目中进行参数校验的内容请看《如何在 Spring/Spring Boot 中做参数校验你需要了解的都在这里》这篇文章。
7. 全局处理 Controller 层异常
介绍一下我们 Spring 项目必备的全局处理 Controller 层异常。
相关注解
ControllerAdvice :注解定义全局异常处理类ExceptionHandler :注解声明异常处理方法
如何使用呢拿我们在第 5 节参数校验这块来举例子。如果方法参数不对的话就会抛出MethodArgumentNotValidException我们来处理这个异常。
复制代码ControllerAdvice
ResponseBody
public class GlobalExceptionHandler {/*** 请求参数异常处理*/ExceptionHandler(MethodArgumentNotValidException.class)public ResponseEntity? handleMethodArgumentNotValidException(MethodArgumentNotValidException ex, HttpServletRequest request) {......}
}更多关于 Spring Boot 异常处理的内容请看我的这两篇文章
SpringBoot 处理异常的几种常见姿势使用枚举简单封装一个优雅的 Spring Boot 全局异常处理
8. JPA 相关
8.1. 创建表
Entity声明一个类对应一个数据库实体。
Table 设置表明
复制代码Entity
Table(name role)
public class Role {IdGeneratedValue(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 中常见的主键生成策略如下
Guide 哥枚举替代常量的一种用法
复制代码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 提供的主键生成策略有如下几种
复制代码public class DefaultIdentifierGeneratorFactoryimplements MutableIdentifierGeneratorFactory, Serializable, ServiceRegistryAwareService {SuppressWarnings(deprecation)public DefaultIdentifierGeneratorFactory() {register( uuid2, UUIDGenerator.class );register( guid, GUIDGenerator.class ); // can be done with UUIDGenerator strategyregister( uuid, UUIDHexGenerator.class ); // deprecated for new useregister( uuid.hex, UUIDHexGenerator.class ); // uuid.hex is deprecatedregister( assigned, Assigned.class );register( identity, IdentityGenerator.class );register( select, SelectGenerator.class );register( sequence, SequenceStyleGenerator.class );register( seqhilo, SequenceHiLoGenerator.class );register( increment, IncrementGenerator.class );register( foreign, ForeignGenerator.class );register( sequence-identity, SequenceIdentityGenerator.class );register( enhanced-sequence, SequenceStyleGenerator.class );register( enhanced-table, TableGenerator.class );}public void register(String strategy, Class generatorClass) {LOG.debugf( Registering IdentifierGenerator strategy [%s] - [%s], strategy, generatorClass.getName() );final Class previous generatorStrategyToClassNameMap.put( strategy, generatorClass );if ( previous ! null ) {LOG.debugf( - overriding [%s], previous.getName() );}}}8.3. 设置字段类型
Column 声明字段。
示例
设置属性 userName 对应的数据库字段名为 user_name长度为 32非空
复制代码Column(name user_name, nullable false, length32)
private String userName;设置字段类型并且加默认值这个还是挺常用的。
复制代码Column(columnDefinition tinyint(1) default 1)
private Boolean enabled;8.4. 指定不持久化特定字段
Transient 声明不需要与数据库映射的字段在保存的时候不需要保存进数据库 。
如果我们想让secrect 这个字段不被持久化可以使用 Transient关键字声明。
复制代码Entity(nameUSER)
public class User {......Transientprivate String secrect; // not persistent because of Transient}除了 Transient关键字声明 还可以采用下面几种方法
复制代码static String secrect; // not persistent because of static
final String secrect “Satish”; // not persistent because of final
transient String secrect; // not persistent because of transient一般使用注解的方式比较多。
8.5. 声明大字段
Lob:声明某个字段为大字段。
复制代码Lob
private String content;更详细的声明
复制代码Lob
//指定 Lob 类型数据的获取策略 FetchType.EAGER 表示非延迟 加载而 FetchType. LAZY 表示延迟加载
Basic(fetch FetchType.EAGER)
//columnDefinition 属性指定数据表对应的 Lob 字段类型
Column(name content, columnDefinition LONGTEXT NOT NULL)
private String content;8.6. 创建枚举类型的字段
可以使用枚举类型的字段不过枚举字段要用Enumerated注解修饰。
复制代码public enum Gender {MALE(男性),FEMALE(女性);private String value;Gender(String str){valuestr;}
}
复制代码Entity
Table(name role)
public class Role {IdGeneratedValue(strategy GenerationType.IDENTITY)private Long id;private String name;private String description;Enumerated(EnumType.STRING)private Gender gender;省略getter/setter......
}数据库里面对应存储的是 MAIL/FEMAIL。
8.7. 增加审计功能
只要继承了 AbstractAuditBase的类都会默认加上下面四个字段。
复制代码Data
AllArgsConstructor
NoArgsConstructor
MappedSuperclass
EntityListeners(value AuditingEntityListener.class)
public abstract class AbstractAuditBase {CreatedDateColumn(updatable false)JsonIgnoreprivate Instant createdAt;LastModifiedDateJsonIgnoreprivate Instant updatedAt;CreatedByColumn(updatable false)JsonIgnoreprivate String createdBy;LastModifiedByJsonIgnoreprivate String updatedBy;
}我们对应的审计功能对应地配置类可能是下面这样的Spring Security 项目:
复制代码
Configuration
EnableJpaAuditing
public class AuditSecurityConfiguration {BeanAuditorAwareString auditorAware() {return () - Optional.ofNullable(SecurityContextHolder.getContext()).map(SecurityContext::getAuthentication).filter(Authentication::isAuthenticated).map(Authentication::getName);}
}简单介绍一下上面设计到的一些注解 CreatedDate: 表示该字段为创建时间时间字段在这个实体被 insert 的时候会设置值 CreatedBy :表示该字段为创建人在这个实体被 insert 的时候会设置值 LastModifiedDate、LastModifiedBy同理。
EnableJpaAuditing开启 JPA 审计功能。
8.8. 删除/修改数据
Modifying 注解提示 JPA 该操作是修改操作,注意还要配合Transactional注解使用。
复制代码Repository
public interface UserRepository extends JpaRepositoryUser, Integer {ModifyingTransactional(rollbackFor Exception.class)void deleteByUserName(String userName);
}8.9. 关联关系
OneToOne 声明一对一关系OneToMany 声明一对多关系ManyToOne声明多对一关系MangToMang声明多对多关系
更多关于 Spring Boot JPA 的文章请看我的这篇文章一文搞懂如何在 Spring Boot 正确中使用 JPA 。
9. 事务 Transactional
在要开启事务的方法上使用Transactional注解即可!
复制代码Transactional(rollbackFor Exception.class)
public void save() {......
}我们知道 Exception 分为运行时异常 RuntimeException 和非运行时异常。在Transactional注解中如果不配置rollbackFor属性,那么事物只会在遇到RuntimeException的时候才会回滚,加上rollbackForException.class,可以让事物在遇到非运行时异常时也回滚。
Transactional 注解一般用在可以作用在类或者方法上。
作用于类当把Transactional 注解放在类上时表示所有该类的public 方法都配置相同的事务属性信息。作用于方法当类配置了Transactional方法也配置了Transactional方法的事务会覆盖类的事务配置信息。
更多关于关于 Spring 事务的内容请查看
可能是最漂亮的 Spring 事务管理详解一口气说出 6 种 Transactional 注解失效场景
10. json 数据处理
10.1. 过滤 json 数据
JsonIgnoreProperties 作用在类上用于过滤掉特定字段不返回或者不解析。
复制代码//生成json时将userRoles属性过滤
JsonIgnoreProperties({userRoles})
public class User {private String userName;private String fullName;private String password;JsonIgnoreprivate ListUserRole userRoles new ArrayList();
}JsonIgnore一般用于类的属性上作用和上面的JsonIgnoreProperties 一样。
复制代码
public class User {private String userName;private String fullName;private String password;//生成json时将userRoles属性过滤JsonIgnoreprivate ListUserRole userRoles new ArrayList();
}10.2. 格式化 json 数据
JsonFormat一般用来格式化 json 数据。
比如
复制代码JsonFormat(shapeJsonFormat.Shape.STRING, patternyyyy-MM-ddTHH:mm:ss.SSSZ, timezoneGMT)
private Date date;10.3. 扁平化对象
复制代码Getter
Setter
ToString
public class Account {JsonUnwrappedprivate Location location;JsonUnwrappedprivate PersonInfo personInfo;GetterSetterToStringpublic static class Location {private String provinceName;private String countyName;}GetterSetterToStringpublic static class PersonInfo {private String userName;private String fullName;}
}未扁平化之前
复制代码{location: {provinceName:湖北,countyName:武汉},personInfo: {userName: coder1234,fullName: shaungkou}
}使用JsonUnwrapped 扁平对象之后
复制代码Getter
Setter
ToString
public class Account {JsonUnwrappedprivate Location location;JsonUnwrappedprivate PersonInfo personInfo;......
}
复制代码{provinceName:湖北,countyName:武汉,userName: coder1234,fullName: shaungkou
}11. 测试相关
ActiveProfiles一般作用于测试类上 用于声明生效的 Spring 配置文件。
复制代码SpringBootTest(webEnvironment RANDOM_PORT)
ActiveProfiles(test)
Slf4j
public abstract class TestBase {......
}Test声明一个方法为测试方法
Transactional被声明的测试方法的数据会回滚避免污染测试数据。
WithMockUser Spring Security 提供的用来模拟一个真实用户并且可以赋予权限。
复制代码 TestTransactionalWithMockUser(username user-id-18163138155, authorities ROLE_TEACHER)void should_import_student_success() throws Exception {......}暂时总结到这里吧虽然花了挺长时间才写完不过可能还是会一些常用的注解的被漏掉所以我将文章也同步到了 Github 上去Github 地址github.com/Snailclimb/… 欢迎完善
本文已经收录进我的 75K Star 的 Java 开源项目 JavaGuidegithub.com/Snailclimb/…。