JAVA中的自定义注解

JAVA中的自定义注解

一、注解的定义
java注解可以理解为一种的程序特性的标注,该标注代表某一种功能,可在运行时反射来动态实现功能映射,也有作用于源码和字节码的。其中,用来标记自定义注解的称为元注解
(meta-annotation),有Target、Retention、Documented和Inherited。

二、元注解
元注解是用于修饰其它注解的注解。 JDK5.0提供了四种元注解:Retention, Target, Documented, Inherited
1、@Retention:用于指定修饰的注解的生命周期,@Rentention包含一个RetentionPolicy枚举类型的成员变量,使用@Rentention时必须为该value成员变量指定值:
SOURCE:只在源文件中有效,编译器直接丢弃这种策略的注释,在.class文件中不会保留注解信息。反编译查看字节码文件:发现字节码文件中没有MyAnnotation这个注解
CLASS: 在class文件中有效,保留在.class文件中,但是当运行Java程序时,不会继续加载了,不会保留在内存中,JVM不会保留注解。
如果注解没有加Retention元注解,那么相当于默认的注解就是这种状态。
RUNTIME:在运行时有效(即运行时保留),当运行 Java程序时,JVM会保留注释,加载在内存中了,那么程序可以通过反射获取该注释。
2、@Target:用于修饰注解的注解,用于指定被修饰的注解能用于修饰哪些程序元素,即修饰位置。@Target也包含一个名为value的成员变量。
3、@Documented:用于指定被该元注解修饰的注解类将被javadoc工具提取成文档。默认情况下,javadoc是 不包括注解的,但是加上了这个注解生成的文档中就会带着注解了
4、@Inherited: 被它修饰的Annotation将具有继承性。如果某个类使用了被 @Inherited修饰的Annotation,则其子类将自动具有该注解。

三、注解属性定义
注解属性 ( 接口方法 ) 返回值类型要求 :
基本数据类型 : byte , short , int , long , float , double , char , boolean ;
字符串类型 : String ;
枚举类型 : enum ;
注解类型 ;
以上类型的数组形式 ;
可以使用default来进行赋默认值
案例:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AdminLoginToken {
    @AliasFor("admin")
    boolean value() default true;

    @AliasFor("value")
    boolean admin() default true;
}

四、使用案例演示
模拟是否需要进行登录校验;如果方法中加上了@LoginRequired注解表示方法需要登录校验,如果没加则不需要。定义一个

@LoginRequired注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public@interface LoginRequired {
    
}

定义两个简单接口,其中一个添加@LoginRequired注解表示需要登录校验

@RestController
public class UserController {
    @GetMapping("/login1")
    public TransDTO login1(){
        return new TransDTO<>().withMessage("访问login1成功").withCode(HttpStatus.OK.value());
    }
    
    @LoginRequired
    @GetMapping("/login2")
    public TransDTO login2(){
        return new TransDTO<>().withMessage("访问login2成功").withCode(HttpStatus.OK.value());
    }
}

自定义拦截器

@Configuration
public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("访问了过滤器!");
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        LoginRequired annotation = handlerMethod.getMethod().getAnnotation(LoginRequired.class);
        if(annotation != null){
            //全局异常处理会进行处理
            throw new BusinessException("访问失败,您没有权限访问!");
        }
        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     {

    }
}

配置拦截路径

@Configuration
public class InterceptorTrainConfigurer implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**");
    }
}

全局异常处理

@RestControllerAdvice
public class MyExceptionAdvice {
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.OK)
    public TransDTO handleException(HttpServletRequest request,Exception e){
        e.printStackTrace();
        return new TransDTO().withCode(500).withSuccess(false).withMessage(e.getMessage());
    }
}

访问结果
JAVA中的自定义注解_第1张图片

五、总结
自定义注解的场景有很多,比如登录、权限拦截、日志、以及各种框架。java注解对于性能有较大的影响,但可用于软件的架构设计,实现动态加载,对于分解复杂业务有帮助。

你可能感兴趣的:(java基础,java,jvm,开发语言)