在开发SpringBoot程序的过程中,有可能与其他业务系统进行对接开发,获取封装公共的API接口等等,有的时候为了开发的便捷性以及间接性,会需要开发一些自定义的注解,来实现一些业务。
下面就来说一下在SpringBoot里开发自定义注解。
一:
首先看一下完整的结构图:
在进行开发自定义注解前需要在POM文件中添加aop依赖
org.springframework.boot
spring-boot-starter-aop
1.创建annotation文件夹(名字随意),然后创建注解类,注意这是一个@interface,在Kind出选择Annotation
下面来代码:
package com.**.***.项目名.annotation;
import java.lang.annotation.*;
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Token {
String value() default "";
}
关于@Target @Retention @Documented这几个注解可以查看一下这个文件
https://blog.csdn.net/liang100k/article/details/79515910
切面类具体代码:
package com.**.***.项目名称.Aspect;
import com.**.***.项目名称.common.Decrypt;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* @ClassName TokenAspect
* @Description token校验自定义注解
* @Author wangjian
* @Date 19/06/25 13:29
* @Version <1.0>
*/
@Aspect
@Component
@SuppressWarnings({"unused"})
public class TokenAspect {
public static final Logger logger = LoggerFactory.getLogger(TokenAspect.class);
public static final String TOKEN_KEY = "token";
/**
* checkUrl,keyUrl,tokenScope是通过Spring的@Value注解来获取配置文件中的配置项
* @Value等同于Spring原先的配置模式中的value
*
*
*
*/
@Value(value = "${jwt.checkUrl}")
String checkUrl;
@Value(value = "${jwt.keyUrl}")
String keyUrl;
@Value(value = "${jwt.clientId}")
String tokenScope;
@Pointcut("@annotation(com.**.***.项目名.annotation.Token)")
public void annotationPointcut() {
}
@Before("annotationPointcut()")
public void beforePointcut(JoinPoint joinPoint) {
// 此处进入到方法前 可以实现一些业务逻辑
}
@Around("annotationPointcut()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
String[] params = methodSignature.getParameterNames();// 获取参数名称
Object[] args = joinPoint.getArgs();// 获取参数值
if (null == params || params.length == 0){
String mes = "Using Token annotation, the token parameter is not passed, and the parameter is not valid.";
logger.info(mes);
throw new Exception(mes);
}
boolean hasToken = false;
int index = 0;
for (int i = 0; i < params.length; i++) {
if (TOKEN_KEY.equals(params[i])) {
hasToken = true;
index = i;
break;
}
}
if (!hasToken){
String mes = "The token parameter is not included in the requested parameter, the parameter is not valid.";
logger.info(mes);
throw new Exception(mes);
}
this.checkToken(String.valueOf(args[index]));
return joinPoint.proceed();
}
/**
* 在切入点return内容之后切入内容(可以用来对处理返回值做一些加工处理)
* @param joinPoint
*/
@AfterReturning("annotationPointcut()")
public void doAfterReturning(JoinPoint joinPoint) {
}
private void checkToken(String token) {
Decrypt decrypt = new Decrypt();// 这个类是自己的业务类,主要进行token验证(JWT)
try {
decrypt.check(token, checkUrl, keyUrl, tokenScope);
} catch (Exception e) {
logger.info(e.getMessage());
throw new RuntimeException(e.getMessage());
}
}
}
上面基本上完成了自定义注解的开发,在使用中可以直接使用@Token即可。如:
/**
* 使用了@Token,如果在切面类中没有经过校验验证,会直接抛出异常,checkToken方法中不会进入
*/
@Token
@RequestMapping(value = "checkToken", method = RequestMethod.POST)
public String checkToken(@RequestParam String token) {
// 自己的业务实现
return null;
}
下面是完成的pom文件
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.0.5.RELEASE
com.**.***
项目名
0.0.1-SNAPSHOT
项目名
Demo project for Spring Boot
UTF-8
UTF-8
1.8
org.springframework.boot
spring-boot-starter-thymeleaf
org.springframework.boot
spring-boot-starter-logging
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-logging
org.springframework.boot
spring-boot-starter-aop
org.springframework.boot
spring-boot-configuration-processor
true
org.projectlombok
lombok
true
io.springfox
springfox-swagger2
2.8.0
io.springfox
springfox-swagger-ui
2.8.0
org.mybatis.spring.boot
mybatis-spring-boot-starter
org.springframework.boot
spring-boot-starter-logging
1.3.2
org.springframework.boot
spring-boot-starter-actuator
mysql
mysql-connector-java
runtime
com.alibaba
druid-spring-boot-starter
1.1.0
org.slf4j
slf4j-api
1.7.21
org.slf4j
slf4j-log4j12
1.7.21
commons-logging
commons-logging
1.2
com.ctrip.framework.apollo
apollo-client
1.1.0
com.ctrip.framework.apollo
apollo-core
1.1.0
org.bitbucket.b_c
jose4j
0.6.5
net.sf.json-lib
json-lib
2.2.3
jdk13
org.apache.httpcomponents
httpclient
4.5.2
org.apache.httpcomponents
httpcore
4.4.6
org.springframework.boot
spring-boot-starter-test
org.springframework.boot
spring-boot-starter-logging
test
org.springframework.boot
spring-boot-maven-plugin
org.apache.maven.plugins
maven-compiler-plugin
8