Java基础 - 注解

引言

第一次感受到注解的威力是在使用springboot时,一个注解就能启动一个Web应用,非常厉害,同时又有点神秘
添加一些三方组件时,例如eureka,只需要添加一个注解,加几行配置就能启动一个Eureka Server,客户端也是,添加一个注解就能注册上去(后面不知道哪个版本之后连注解都不需要加了,这里暂不讨论),注解变得愈发神秘
但后面学习注解之后,发现其实注解的知识点并不多也不难,这里记录下相关的笔记吧

作用

个人理解的注解:实际上就是一种加强版的注释,为什么是加强版的呢?因为它能被反射读到,反射的强大,大家应该都有所了解,所以注解本身并没有任何作用,起作用的是反射,注解只是为类,属性,方法等添加一种描述而已

就好比说现在是在战争演习,红蓝双方各自戴着红色及蓝色的帽子,这顶帽子本身无法起到什么作用,不会让你跑的更快,射的更准,它的作用是由你的队友或者对手体现的:

  • 队友通过帽子的颜色发现你是自己人,不会误伤你,还会给你发各种信号
  • 对手通过帽子的颜色发现你是敌人,上来就是一枪,GG。。
    所以帽子本身只是对你身份的另一种描述而已,比如帽子一脱,你该打的还是能打,该开炮的还是能开炮,只是其他人无法通过帽子分辨你是友军还是敌军了而已(少了这个额外的功能),并不会影响你自己的功能

几个小栗子

  • 例如Junit,它的规则就是所有加了@Test注解的方法我都会自动执行,这个过程简单说就是下面这样:
1. 测试类启动,通过反射获取所有的方法
2. 遍历方法,通过反射拿到方法注解
3. 是否存在@Test注解?  
       存在?   --- 执行方法  
       不存在? --- 跳过
  • 再例如我们如果想实现SpringAOP可以怎么做,比如说我们想给所有打了@Log的方法添加日志(一般会通过切面来做,这里我们假设注解都是自己手动打在方法上的),那我们要做的事情实际上就是两件
1. 找到每个Bean中包含@Log注解的方法
2. 使用动态代理(这里我们假设使用的是JDK动态代理),生成一个代理类Proxy,然后把原来的类强转成这个代理类,为啥可以强转?因为  

至于如何让每个Bean都走我这个方法?可以了解下BeanPostProcessor这个接口,实现这个接口,每个Bean都会走你的实现类

  • 再例如我们想实现一个简单的SpringMVC怎么做,这里就留给大家自己思考吧?核心就是将请求的url和类及方法联系起来

使用

定义注解

定义注解主要就是三个方面:

  1. 适用类型(可以定义在哪些地方)
  2. 存活策略(一般都是RUNTIME)
  3. 注解的各种属性
  4. 属性可以设置默认值
  • 所有基本类型(int、float、boolean等)
  • String
  • Class
  • enum
  • Annotation
  • 以上类型的数组

整个简单的,我想定义一个自己的RequestMapping注解,value是url,方法类型是method(默认值给成"GET")

@Target(value = {ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyRequestMapping {
    String value();
    String method() default "GET";
}

完成,就是这么简单

使用注解

像字段属性一样赋值,像调用方法一样拿值

// @MyRequestMapping("/test")
@MyRequestMapping(value = "/test",method = "POST")
public class AnnoTest {

    public static void main(String[] args) {
        MyRequestMapping annotation = AnnoTest.class.getAnnotation(MyRequestMapping.class);
        if(annotation != null) {
            System.out.println(annotation.value());
            System.out.println(annotation.method());
        }
    }

}

完成,还是这么简单

使用注解的小提示

如果存在value属性,并且只想给value这一个属性赋值的话,那么可以省略属性名,因为默认就是给value属性赋值的。
比如说可以把上面这个例子中的@MyRequestMapping(value = "/test",method = "POST")替换成@MyRequestMapping("/test"),看看打印结果

posted @ 2021-03-28 13:20  calmbook  阅读(48)  评论(0编辑  收藏  举报