@Api
Swagger 中的一个注解,用于指定一个类的方法或者字段的 API 相关信息。在 Spring Boot 项目中,通常用于 Swagger 文档的生成。
| @Api | 修饰controller类,标识这个类是swagger的资源 |
|---|---|
| @ApiOperation | 修饰controller的方法,表示一个http请求的操作 |
| @ApiParam | 修饰方法的参数,用于添加参数说明与是否必填等元数据 |
例子:
@Api(tags={"用户操作接口"})
@RestController
public class UserController {
@ApiOperation(value="获取用户信息",tags={"获取用户信息copy"},notes="注意问题点")
@GetMapping("/getUserInfo")
public User getUserInfo(@ApiParam(name="id",value="用户id",required=true) Long id,@ApiParam(name="username",value="用户名") String username) {
// userService可忽略,是业务逻辑
User user = userService.getUserInfo();
return user;
}
}
@Autowired/@Resource
依赖注入。
1.来源不同
Autowired 和 Resource 注解来自不同的“父类”,其中Autowired注解是 Spring 定义的注解,而Resource 注解是 Java 定义的注解,它来自于 JSR-250(Java 250 规范提案)。
2、注入规则不同
Autowired注解是spring的注解,此注解只根据type进行注入,不会去匹配name。但是如果只根据type无法辨别注入对象时,就需要配合使用@Qualifier注解或者@Primary注解使用。
Resource注解有两个重要的属性,分别是name和type,如果name属性有值,则使用byName的自动注入策略,将值作为需要注入bean的名字,如果type有值,则使用byType自动注入策略,将值作为需要注入bean的类型。如果既不指定name也不指定type属性,这时将通过反射机制使用byName自动注入策略。即@Resource注解默认按照名称进行匹配,名称可以通过name属性进行指定,如果没有指定name属性,当注解写在字段上时,默认取字段名,按照名称查找,当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。
3、依赖查找的顺序不同
Autowired注解先根据类型(byType)查找,如果存在多个(Bean)再根据名称(byName)进行查找;
Resource注解先根据名称(byName)查找,如果(根据名称)查找不到,再根据类型(byType)进行查找。
4、支持的参数不同
Autowired注解只支持设置 1 个参数,而Resource注解支持设置 7 个参数。
5、依赖注入的用法支持不同
Autowired注解支持属性注入、构造方法注入和 Setter 注入,而Resource注解只支持属性注入和 Setter 注入。
6、编译器 IDEA 的提示不同
当使用 IDEA 专业版在编写依赖注入的代码时,如果注入的是 Mapper 对象,那么使用Autowired注解编译器会提示报错信息。虽然 IDEA 会出现报错信息,但程序是可以正常执行的。 然后,我们再将依赖注入的注解更改为Resource注解就不会出现报错信息了
7、使用位置不同
两者都可以写在字段和setter方法上,如果写在字段上,那么就不需要在写setter方法。推荐使用Resource注解在字段上,这样不仅不需要写setter方法了,而且由于Resource注解属于J2EE,降低与spring的耦合。
共同点
- @Resource注解和@Autowired注解都可以用作bean的注入;
- 在接口只有一个实现类的时候,两个注解可以互相替换,效果相同。
@PathVariable
获取url中的数据,绑定路径中的占位符参数到方法参数变量中.
如果没有指定 required 属性,或者设置为 true(默认值),则该路径变量是必需的。如果路径中缺少这个变量或者变量不匹配,将会抛出异常。
// 假设 URL 模板为 "/users/{userId}",userId 是必需的
@RequestMapping(value = "/users/{userId}", method = RequestMethod.GET)
public String getUser(@PathVariable(name = "userId", required = true) String userId) {
// 方法实现
}
// 如果 userId 不是必需的,可以这样设置
@RequestMapping({"/statusCount/{outletId}","/statusCount/"})
public String getUserOptional(@PathVariable(required = false) String outletId) {
// 方法实现
}
设置成false,不带参数时,应该可以做到全局搜索
@Qualifier
区分具有相同类型的多个Bean,用于明确指定要注入的Bean的名称或限定符。通常为要注入的Bean添加
如:有一个UserService接口,但有两个实现类。就需要使用qualifier,不然不知道是哪个实现类,会报NoUniqueBeanDefinitionException异常
例子:
- 在定义Bean的地方,使用@Qualifier注解为Bean添加一个限定符,这个限定符可以是任何字符串,用于区分同一类型的多个Bean。
@Bean
@Qualifier("database")
public DataSource dataSource() {
// 返回一个数据库数据源的实现
return new DatabaseDataSource();
}
- 在需要进行注入Bean的地方,使用@Qualifier注解并指定相同的限定符值,具体来说,假设有两个名为"databaseDataSource"和"fileDataSource"的DataSource类型的Bean,并且它们都使用了@Qualifier注解并指定了不同的限定符值。
@Autowired
@Qualifier("database")
private DataSource dataSource;
@PreAuthorize
在方法执行前进行权限验证
这个是由spring security提供的。Spring Security提供了Spring EL表达式,允许我们在定义接口访问的方法上面添加注解,来控制访问权限
| 方法 | 参数 | 描述 |
|---|---|---|
| hasPermi | String | 验证用户是否具备某权限 |
| lacksPermi | String | 验证用户是否不具备某权限,与hasPermi逻辑相反 |
| hasAnyPermi | String | 验证用户是否具有以下任意一个权限 |
| hasRole | String | 判断用户是否拥有某个权限 |
| lacksRole | String | 验证用户是否不具备某个权限,与hasRole逻辑相反 |
| hasAnyRoles | String | 验证用户是否具有以下任意一个角色,多个逗号分隔 |
其中@ss代表的是PermissionService (opens new window)服务,对每个接口拦截并调用PermissionService的对应方法判断接口调用者的权限。
A. ss 是一个注册在 Spring容器中的BEAN,对应的类是cn.hadoopx.framework.web.service.PermissionService;
B. hasPermi 是PermissionService类中定义的方法;
C.当Spring EL 表达式返回TRUE,则权限校验通过;
1.数据示例
// 符合system:user:list权限要求
@PreAuthorize("@ss.hasPermi('system:user:list')")
// 不符合system:user:list权限要求
@PreAuthorize("@ss.lacksPermi('system:user:list')")
// 符合system:user:add或system:user:edit权限要求即可
@PreAuthorize("@ss.hasAnyPermi('system:user:add,system:user:edit')")
2.角色权限示例
// 符合system:user:list权限要求
@PreAuthorize("@ss.hasPermi('system:user:list')")
// 不符合system:user:list权限要求
@PreAuthorize("@ss.lacksPermi('system:user:list')")
// 符合system:user:add或system:user:edit权限要求即可
@PreAuthorize("@ss.hasAnyPermi('system:user:add,system:user:edit')")
@Async和@EnableAsync
解释
异步的优点:
- 提高应用程序的响应能力
- 提高系统的吞吐量
- 节约资源:异步操作可以避免在请求处理期间占用过多的线程资源,减少服务器的负载。
- 优化用户体验
需要注意的问题:
- 事务问题:异步处理时,需要注意在事务没有结束时做异步操作,可能会导致读取不到甚至覆盖事务中新增或更新的数据内容。
在 Spring Boot 中,可以通过 @EnableAsync 注解来启动异步方法调用的支持,通过 @Async 注解来标识异步方法,
1.@EnableAsync 注解
@EnableAsync是一个 Spring Boot 中用于启动异步方法调用的注解。使用@EnableAsync注解时,需要将其放置在一个配置类上,并且在配置类中通过@Bean方法创建一个线程池。
2.@Async 注解
@Async注解是一个 Spring Boot 中用于标识异步方法的注解,通过在方法上添加@Async注解,可以让该方法在异步线程中执行。
- 假如只配置了一个线程池,直接用
@Async注解就会用自定义的线程池执行。 - 假如配置了多个线程池,用
@Async("name")来指定使用哪个线程池,如果没有指定,会用默认的 SimpleAsyncTaskExecutor 来处理。
@Data
@Data注解是Lombok库中的一个功能强大的注解,它自动为类生成一系列有用的方法,从而显著减少样板代码的编写工作。
依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
<scope>provided</scope>
</dependency>
提供的方法:
- 其他相关注解
@Data : 注在类上,提供类的get、set、equals、hashCode、toString等方法
@AllArgsConstructor :注在类上,提供类的全参构造
@NoArgsConstructor :注在类上,提供类的无参构造
@Setter :注在属性上,提供 set 方法
@Getter :注在属性上,提供 get 方法
@EqualsAndHashCode :注在类上,提供对应的 equals 和 hashCode 方法
@Log4j/@Slf4j :注在类上,提供对应的 Logger 对象,变量名为 log
@ConfigurationProperties
作用
@ConfigurationProperties注解(将配置文件中的配置,以属性的形式自动注入到实体中)可以注入在application.properties配置文件中的属性,和@Bean 或者 @Component 等能生成spring bean 的注解结合起来使用;
原理
注入后该类在加载过程中会调用AbstractAutowireCapableBeanFactory中的applyBeanPostProcessorsBeforeInitialization接口进行一些前置处理。
@ConfigurationProperties 注解其对应的bean的后置处理器为ConfigurationPropertiesBindingPostProcessor,
它实现了Spring容器的postProcessBeforeInitialization方法,会在bean初始化之前被调用注解处理器会读取@ConfigurationProperties 注解的对象获取配置文件中的prefix,和注解对象的类成员变量然后递归将配置属性赋值给类成员变量。
和@value获取值进行比较
注意:
1、要特别说明的一个注属性 ignoreUnknownFields = false 这个超好用,自动检查配置文件中的属性是否存在,不存在则在启动时就报错。
2、必须在pom.xml文件中配置该注解,否则报错:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
3、@ConfigurationProperties注解支持属性文件和javabean的映射,而@Value支持spel表达式。如果是多个属性映射,而且常常被复用,推荐使用@ConfigurationProperties,如果只读取单个属性则使用@Value要方便许多。
4、在JavaBean类上或与@Bean注解使用时,必须在使用到的JavaBean类上面添加@Component,否则在容器无法获取,若只使用@ConfigurationProperties需要结合@EnableConfigurationProperties(PropertisInject.class)将其注册到spring容器中。