java注解


java注解概述

Java 注解用于为 Java 代码提供元数据。作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的。Java 注解是从 Java5 开始添加到 Java 的。


java中常见的注解
  • @Override 表示方法打算重写抽象类或接口里的方法声明,如果方法有此注解但没有重写方法,则编译器会报错。
  • @Deprecated 注释的程序元素,不鼓励程序员使用这样的元素,通常是因为它已经过时了,编译器会发出警告。
  • @SuppressWarnings(“deprecation”) 指示程序取消指定的编译器警告。如取消@Deprecated 产生的警告。
  • @Autowired
  • @Service
  • @Repository

注解分类
  1. 按运行机制分:源码注解、编译时注解、运行时注解
  2. 按来源分:JDK的注解、第三方的注解、自定义注解
  3. 元注解(注解的注解)

源码注解:注解只在源码中存在,编译成.class文件就不存在了。
编译时注解:注解在源码和.class文件中都存在(例如JDK注解:@Override、@Deprecated、@Suppvisewarnings)。
运行时注解:运行阶段还起作用,甚至会影响运行逻辑的注解(例如:Spirng提供的@Autowired注解,程序运行时,把成员变量自动注入)。


自定义注解
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface Description {

    String desc();

    String author();

    int age() default 18;

}

@Target 表示注解作用域

public enum ElementType {
   TYPE,//用于描述类、接口(包括注解类型) 或enum声明
   FIELD, //用于描述成员变量;
   METHOD,//用于描述方法
   PARAMETER,//用于描述参数
   CONSTRUCTOR,//用于描述构造器
   LOCAL_VARIABLE,//用于描述局部变量;
   ANNOTATION_TYPE,//注解类型声明 该注解可用于描述注解
   PACKAGE,//用于描述包
   TYPE_PARAMETER,//这个是jdk1.8后加入的类型  表示这个 Annotation 可以用在 Type 的声明式前
   TYPE_USE//表示这个 Annotation 可以用在所有使用 Type 的地方(如:泛型,类型转换等)
}

@Retention 表示注解生命周期

public enum RetentionPolicy {
    SOURCE,//表示描述程序编译时
    CLASS,//在class文件中有效(即class保留
    RUNTIME//在运行时有效(即运行时保留)
}

@Inherited 允许子类继承。如果在父类上标识该注解,解析一个子类,子类也可以获取该注解
@Documented 生成javadoc时会包含注解

补充:1、注解成员类型是受限的,合法的类型包括原始类型及String、Class、Annotation、Enumeration
2、如果注解只有一个成员,则成员名必须取名为value(),


基于反射解析注解
@Description("I am interface")
public class Person {

    @Description("I am interface method")
    public String name() {
        return null;
    }

}

解析步骤:

  1. 使用类加载器加载类
Class c=Class.forName("com.ann.test.Child");
  1. 找到类上面的注解
boolean isExist=c.isAnnotationPresent(Description.class);
  1. 获取类上自定义注解实例,需要强制类型转换。
Description d=(Description)c.getAnnotation(Description.class);
  1. 获取方法上的注解,首先,遍历所有方法,通过方法对象的isAnnotation查看是否有自定义注解,如果存在则输出方法的自定义注解的信息。

实战-自定义注解实现token验证

注解

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

AOP

@Component
@Aspect
public class TokenAspect {

    @Autowired
    private HttpServletRequest request;
    @Autowired
    private HttpServletResponse response;
    @Autowired
    private AnnotationController controller;

    @Pointcut("within(com.timing.controller..*)")
    public void checkToken () {}

    /**
     * 拦截请求,判断是否带有token
     * @param joinPoint
     * @throws IOException
     */
    @Before("checkToken()")
    public void checkToken (JoinPoint joinPoint) throws IOException {

        MethodSignature signature = (MethodSignature)joinPoint.getSignature();
        //获取当前访问的类方法
        Method targetMethod = signature.getMethod();
        //判断是否是注解修饰的类,如果是则不需要校验token
        if(!targetMethod.isAnnotationPresent(IgnoreToken.class)){
            String token = request.getParameter("token");
            if (StringUtils.isEmpty(token)) {
                response.setCharacterEncoding("utf-8");
                response.setContentType("application/json; charset=utf-8");
                PrintWriter out = response.getWriter();
                out.print("token不能为空");
                out.flush();
                out.close();
            } else {
                if (!controller.checkToken(token)) {
                    response.setCharacterEncoding("utf-8");
                    response.setContentType("application/json; charset=utf-8");
                    PrintWriter out = response.getWriter();
                    out.print("token不合法");
                    out.flush();
                    out.close();
                }
            }
        }
    }

}

Controller

@RestController
@RequestMapping(value = "/annotation")
public class AnnotationController {

    public static Map<String,String> map = new HashMap<>();
    public static List<String> logList = new ArrayList<>();
    public static Set<String> tokenSet = new HashSet<>();

    @RequestMapping(value = "login")
    @IgnoreToken
    @Log
    public String login(String userName,String password) {
        map.put(userName,password);
        //保存token
        tokenSet.add(userName+password);
        //返回token
        return userName+password;
    }

    @RequestMapping(value = "query")
    @Log(name = "获取密码")
    public String getPassword(String userName) {
        //获取用户密码
        return map.get(userName);
    }

    @RequestMapping(value = "logs")
    @Log(name = "获取日志信息")
    public String getLogMap() {
        return new Gson().toJson(logList);
    }

    /**
     * 验证token合法性
     * @param token
     * @return
     */
    public boolean checkToken(String token) {
    	//TOTO:根据实际需求来
        return true;
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值