目录
1、注解类型
Java 注解用于为 Java 代码提供元数据,可以通过反射来获取指定注解对象,然后获取注解中的元数据信息。
Java注解有四个标准的元注解:@Target、@Retention、@Documented、@Inherited。
1.1 @Target
@Target说明了Annotation所修饰的对象范围,常用如下:
-
@Target(ElementType.TYPE): 作用接口、类、枚举、注解
-
@Target(ElementType.FIELD) :作用属性字段、枚举的常量
-
@Target(ElementType.METHOD): 作用方法
-
@Target(ElementType.PARAMETER): 作用方法参数
1.2 @Retention
Retention 定义了该 Annotation 被保留的时间长短,表示需要在什么级别保存注解信息,用于描
述注解的生命周期(即:被描述的注解在什么范围内有效)
-
@Retention(RetentionPolicy.SOURCE) 注解仅存在于源码中,在class字节码文件中不包含
-
@Retention(RetentionPolicy.CLASS) 默认的策略,在class字节码文件中存在,但运行时无法获得
-
@Retention(RetentionPolicy.RUNTIME) 在class字节码文件中存在,在运行时可以通过反射获取到
开发中在进行自定义注解的使用时,是在程序运行期间,所以默认就使用@Retention(RetentionPolicy.RUNTIME)
1.3 @Documented
@ Documented它的作用是能够将注解中的元素包含到 Javadoc 中去。
1.4 @Inherited
@Inherited 元注解是一个标记注解,@Inherited 阐述了某个被标注的类型是被继承的。
拥有@Inherited元注解的注解,修饰的一个类并且该类的子类没有被其他注解修饰,则它的子类会继承了父类的注解。
2、自定义注解实现
- 自定义注解可以配合AOP使用,比如:记录日志。
- 自定义注解可以直接在某个方法中,配合反射机制使用。
- 自定义注解可以配合拦截器使用,是否验证token。
2.1 创建注解
创建自定义注解:SysLog
注解可以没有任何属性字段
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SysLog {
/**
* 所属模块
*/
String model() default "";
/**
* 接口名称
*/
String name() default "";
/**
* 功能code
*
* @return
*/
String[] code() default "";
}
2.2 AOP实现
参加AOP类SysLogAspect
,将自定义注解SysLog
作为切入点,如下:
@Aspect
@Component
public class SysLogAspect {
/**
* 过滤类
* 指定自定义注解为切入点
**/
@Pointcut("@annotation(com.lhz.mail.test.SysLog)")
public void logPoint() {
}
/**
* 环绕通知,调用目标方法
*/
@Around("logPoint()")
public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
Signature signature = proceedingJoinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
if (method != null) {
SysLog sysLog = method.getAnnotation(SysLog.class);
// 获取注解的属性值
String[] code = sysLog.code();
String name = sysLog.name();
String model = sysLog.model();
System.out.println("code:" + Arrays.toString(code));
System.out.println("name:" + name);
System.out.println("model:" + model);
}
return proceedingJoinPoint.proceed();
}
}
2.3 反射实现
可以直接利用,反射机制判断,某个类、某个方法、某个字段是否存在注解,如下:
public static void main(String[] args) {
// 判断@SysLog是否存在于Person类上:
Class<Person> clazz = Person.class;
boolean isAnnotation = clazz.isAnnotationPresent(SysLog.class);
if (isAnnotation) {
SysLog sysLog = clazz.getAnnotation((SysLog.class));
String model = sysLog.model();
String name = sysLog.name();
}
}
public static void main2(String[] args) {
// 判断@SysLog是否存在于Person类的方法上:
Class<Person> clazz = Person.class;
// 方法
Method[] methods = clazz.getMethods();
for (Method method : methods) {
boolean isAnnotation = method.isAnnotationPresent(SysLog.class);
if (isAnnotation) {
System.out.println("方法:" + method.getName() + "存在自定义注解");
SysLog sysLog = method.getAnnotation((SysLog.class));
String model = sysLog.model();
String name = sysLog.name();
}
}
}
public static void main3(String[] args) {
// 判断@SysLog是否存在于Person类的字段中:
Class<Person> clazz = Person.class;
// 方法
Field[] fields = clazz.getFields();
for (Field field : fields) {
boolean isAnnotation = field.isAnnotationPresent(SysLog.class);
if (isAnnotation) {
System.out.println("字段:" + field.getName() + "存在自定义注解");
SysLog sysLog = field.getAnnotation((SysLog.class));
String model = sysLog.model();
String name = sysLog.name();
}
}
}
2.4 拦截器实现
配合拦截器判断某个请求是否不需要进行token
校验,逻辑如下:
1、创建注解IgnoreToken
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface IgnoreToken {
}
2、Controller加载注解:
@IgnoreToken
@GetMapping("test")
public Object test() {
return object;
}
3、拦截器判断注解:
@Component
public class AuthenticationHandlerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.debug("进入拦截器,URL:{}", request.getServletPath());
Method method = ((HandlerMethod) handler).getMethod();
// 判断请求接口的方法是否存在IgnoreToken注解
if (method.isAnnotationPresent(IgnoreToken.class)) {
return true;
}else{
// token验证逻辑
...
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/18066.html