SpringBoot自定义注解
2019-07-05 本文已影响0人
消失的码农
spring注解:
一般在记录日志、定时器中使用非常方便,在springmvc框架广泛应用,可以注解的随处可见,近几年流行的springboot框架,更把注解用到了极致,这框架的基本消灭了大部分传统框架上xml配制后改为注解代替,既然注解这么使用这么多,那么如何自定义注解呢
一、自定义注解类编写的一些规则:
- Annotation型 (注解类) 需定义为@interface, 所有的Annotation会自动继承java.lang.Annotation这一接口,并且不能再去继承别的类或是接口.
- 参数成员只能用public或默认(default)这两个访问权修饰
- 参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和String、Enum、Class、annotations等数据类型,以及这一些类型的数组.
- 要获取类方法和字段的注解信息,必须通过Java的反射技术来获取 -Annotation对象,因为你除此之外没有别的获取注解对象的方法
注解也可以没有定义成员, 不过这样注解就没啥用了
二、注解的定义:
- @Documented 注解
指明修饰的注解,可以被例如javadoc此类的工具文档化,只负责标记,没有成员取值。 - @Retention 注解
指明修饰的注解的生存周期,即会保留到哪个阶段。
RetentionPolicy的取值包含以下三种:
SOURCE:源码级别保留,编译后即丢弃
CLASS:编译级别保留,编译后的class文件中存在,在jvm运行时丢弃,这是默认值。
RUNTIME: 运行级别保留,编译后的class文件中存在,在jvm运行时保留,可以被反射调用。
- @Target 注解
功能:指明了修饰的这个注解的使用范围,即被描述的注解可以用在哪里。
ElementType的取值包含以下几种:
TYPE:类,接口或者枚举
FIELD:域,包含枚举常量
METHOD:方法
PARAMETER:参数
CONSTRUCTOR:构造方法
LOCAL_VARIABLE:局部变量
ANNOTATION_TYPE:注解类型
PACKAGE:包
三、具体事例:
- 看注解
@TokenCheck ----->自定义注解
@SystemLog
@RequestMapping(value = "/api/l", method = RequestMethod.POST, consumes = {"application/json"}, produces = {"application/json;charset=UTF-8"})
public ApiResponse entryCapital(@RequestBody CapitalInfoVo capitalInfoVo) {
return basicInfoService.entryCapital(capitalInfoVo);
}
- 定义接口
/**
* Created by duanxufei on 2018/12/12.
*
* 自定义注解,作为TokenCheck切入点
*/
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TokenCheck {
String value() default "";
}
- 对注解进行功能型判断
@Aspect
@Component
public class TokenCheckInterceptor {
private static final Logger logger = LoggerFactory.getLogger(TokenCheckInterceptor.class);
@Autowired
private MerchantService merchantService;
public TokenCheckInterceptor() {
System.out.println("===>check start");
}
@Pointcut("@annotation(com.xf.harbor.config.TokenCheck)")
private void anyMethod() {
}
@Around("anyMethod()")
public Object checkRequestHead(ProceedingJoinPoint joinPoint) throws Throwable {
logger.debug("===>check access token start:{}", joinPoint.getArgs());
long begin = System.nanoTime();
HttpServletRequest request =
((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
request.setCharacterEncoding("UTF-8");
HttpServletResponse response =
((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
String token = request.getHeader("X-XfAuth-Token");
logger.debug("===> request token is {}", token);
String[] listAterTokenSplit = token.split("-");
String ak = listAterTokenSplit[1];
String ipAddr = request.getHeader("X-Real-IP");
if (ipAddr == null || ipAddr.equals("")) {
ipAddr = request.getRemoteAddr();
}
logger.info("request X-Real-IP ipAddr={}", ipAddr);
int expireTime = Integer.parseInt(listAterTokenSplit[2]);
if (expireTime < MyUtil.getCurrentTimestamp()) { //token 超时
writeResponse(response,
new ApiResponse(ResponseCodeEnums.token_timeout.getStatus(), ResponseCodeEnums.token_timeout.getMessage()));
return null;
}
Object[] args = joinPoint.getArgs();
String requestBody = new Gson().toJson(args[0]);
String sk = "";
String allowIps = "";
try {
Merchant merchant = merchantService.getMerchant(ak);
if (merchant != null) {
sk = merchant.getSecretKey();
allowIps = merchant.getAllowIps();
}
logger.info("===> access key is: {}", ak);
//check ipAddr
if (!StringUtils.equals(allowIps, "*")) {
String[] ips = allowIps.split(",");
if (!Arrays.asList(ips).contains(ipAddr)) {
writeResponse(response,
new ApiResponse(ResponseCodeEnums.limited_ip.getStatus(), ResponseCodeEnums.limited_ip.getMessage()));
return null;
}
}
} catch (Exception e) {
e.printStackTrace();
writeResponse(response,
new ApiResponse(ResponseCodeEnums.system_exception.getStatus(), ResponseCodeEnums.system_exception.getMessage()));
return null;
}
String requestUri = request.getRequestURI();
String requestMethod = request.getMethod();
String queryParam = getParamString(request.getParameterMap());
logger.info(
"===>get the equest url:{}; and request method:{}; "
+ "request param is {};request body is {}",
requestUri, requestMethod, queryParam, requestBody);
AuthTokenHelper helper = new AuthTokenHelper();
helper.setAccessKey(ak);
helper.setSecretKey(sk);
if (helper.verifyToken(token, requestUri, requestMethod, queryParam, requestBody)) {
Object o = joinPoint.proceed();
long end = System.nanoTime();
logger.info("API deal time log {}:{}",
joinPoint.getTarget().getClass() + "." + joinPoint.getSignature().getName(),
(end - begin) / 1000000);
return o;
} else {
writeResponse(response,
new ApiResponse(ResponseCodeEnums.token_mismatch.getStatus(), ResponseCodeEnums.token_mismatch.getMessage()));
return null;
}
}
private String getParamString(Map<String, String[]> parameterMap) {
String queryParam = null;
if (parameterMap.size() > 0) {
ArrayList<String> parameterKey = new ArrayList<>(parameterMap.keySet());
Collections.sort(parameterKey);
ArrayList<String> keyQuotValues = new ArrayList<>();
for (String key : parameterKey) {
keyQuotValues.add(String.format("%s=%s", key, parameterMap.get(key)[0]));
}
queryParam = StringUtils.join(keyQuotValues, "&");
}
return queryParam;
}
private void writeResponse(HttpServletResponse response, ApiResponse apiResponse) throws IOException {
logger.info("===>token check failed.return response={}", new Gson().toJson(apiResponse));
String responseMap = new Gson().toJson(apiResponse);
response.setContentType("application/json;charset=utf-8");
response.getOutputStream().write(responseMap.getBytes());
response.flushBuffer();
}
}