Spring自定义注解

Spring自定义注解


(一)自定义注解属性

注解作用目标(多选):ElementType

通过@Target注解进行标注:

1
2
3
4
5
6
7
8
9
10
11
12
@Documented
@Retention(RetentionPolicy.RUNTIME) //注解保留时间:运行时
@Target(ElementType.ANNOTATION_TYPE) //注解作用目标:注解类型
public @interface Target {
/**
* Returns an array of the kinds of elements an annotation type
* can be applied to.
* @return an array of the kinds of elements an annotation type
* can be applied to
*/
ElementType[] value();
}

具体属性详见java.lang.annotation.ElementType。常用的有:

  1. ElementType.TYPE:作用于类、接口(包括注解)、枚举
  2. ElementType.METHOD:作用于方法
  3. ElementType.FIELD:作用于字段(包括枚举常量)
  4. ElementType.PARAMETER:作用于参数
  5. ElementType.CONSTRUCTOR:作用于构造函数
  6. ElementType.ANNOTATION_TYPE:作用于注解类型

注解保留时间(单选):RuntimePolicy

通过@Rentation注解进行标注:

1
2
3
4
5
6
7
8
9
10
@Documented
@Retention(RetentionPolicy.RUNTIME) //注解保留时间:运行时
@Target(ElementType.ANNOTATION_TYPE) //注解作用目标:注解类型
public @interface Retention {
/**
* Returns the retention policy.
* @return the retention policy
*/
RetentionPolicy value();
}

具体属性详见java.lang.annotation.ElementType。常用的有:

  1. ElementType.TYPE:作用于类、接口(包括注解)、枚举
  2. ElementType.METHOD:作用于方法
  3. ElementType.FIELD:作用于字段(包括枚举常量)
  4. ElementType.PARAMETER:作用于参数
  5. ElementType.CONSTRUCTOR:作用于构造函数
  6. ElementType.ANNOTATION_TYPE:作用于注解类型

方法(自定义属性字段)

通过@interface关键字可以自定义注解,类中方法名即为自定义注解中的属性字段名,可以为对象、数组、字符串、枚举……

1
2
3
4
5
6
7
8
9
@Target({ElementType.METHOD, ElementType.TYPE})     //注解目标(多选)
@Retention(RetentionPolicy.RUNTIME) //注解保留时间(单选)
//类名即为自定义注解名
public @interface MethodOrClassRuntimeRequired {
//类中方法名即为自定义注解中的属性字段名,可以为对象、数组、字符串、枚举……
//ElementType[] value();
//RetentionPolicy value();
String key();
}

(二)自定义注解拦截器

Spring中,通过继承org.springframework.web.servlet.handler.HandlerInterceptorAdapter抽象类,即可实现自定义注解拦截器。一共有4个方法供继承:

  1. boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)在注解处理前进行调用(最常用);
  2. void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView):在注解处理时进行调用;
  3. void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex):在注解处理后进行调用;
  4. void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler):在注解处理开始时进行调用

如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class MethodClassRuntimeAnnotationInterceptor extends HandlerInterceptorAdapter {

@Override
//通过重写preHandler,拦截注解,在处理注解前调用
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
//1.首先要通过反射获取到注解
//(1)强转
HandlerMethod handlerMethod = (HandlerMethod) handler;
//(2)获取注解对象:先方法(METHOD)后类(TYPE)
MethodOrClassRuntimeRequired annotation = handlerMethod.getMethodAnnotation(MethodOrClassRuntimeRequired.class);
if (annotation == null) {
annotation = handlerMethod.getBeanType().getAnnotation(MethodOrClassRuntimeRequired.class);
}
//(3)对于无注解的情况,要默认成功
if (annotation == null) {
return true;
}

//2.对注解中的字段进行校验
String key = annotation.key();
return "success".equals(key);
}
}

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
@MethodOrClassRuntimeRequired(key = "success")
public void success() {
System.out.println("success");
}

@MethodOrClassRuntimeRequired(key = "fail")
public void fail() {
System.out.println("fail");
}

public void noAnnotation() {
System.out.println("noAnnotation");
}
-------------本文结束感谢您的阅读-------------
急事可以使用右下角的DaoVoice,我绑定了微信会立即回复,否则还是推荐Valine留言喔( ఠൠఠ )ノ
0%