java注解详解

学习完spring系列之后,发现大量的开发都是基于注解配置的,而且很多框架的源码中都存在着大量的注解,如果需要学习框架的源码,已经了解框架中的注解如何配置,那么就必须对注解有更加深刻的理解。

学习注解时,首先提几个问题

  • 注解是用来干什么的?
    引用官方的概念, Java提供了一种原程序中的元素关联任何信息和任何元数据的途径和方法。
    基本上是八股文,不太能读懂,大概的意思就是让java程序其中的元素能够关联到一些数据信息。使用我的理解解读一下:注解就是一种用来为java程序的元素(类,接口,函数)增加标注的方式,但是增加标注的目的是为了信息能够被读取,然后针对标注的信息对其做一些处理。
  • 使用注解有什么好处?
    使用注解能够大大的简化我们的开发,可以使编码更加简介,增添了一种新的方式对功能进行拓展。
  • java中的注解有哪几类
    • java原生注解,@Override
    • jar包里面框架为我们提供的第三方注解@bean
    • 自定义注解,由我们自己编写的注解

来通过几个案例理解一下注解的概念。

  • 原生注解
    @Deprecated这个注解被使用在方法上面,最后被编译器来读取,如果编译器读取到这个注解之后,就会提示我们这个方法已经过时,提醒我们不要使用。
public interface Person {
    public String name();

    public int age();

    /*@Deprecated 表示该方法已经过时了*/
    @Deprecated
    public void sing();
    /*注:
     当方法或是类上面有@Deprecated注解时,
     说明该方法或是类都已经过期不能再用,
     但不影响以前项目使用,提醒你新替代待的方法或是类
     */
}

第三方注解
在这里插入图片描述
在这里插入图片描述
Autowired将成员变量自动注入进来
在这里插入图片描述
Autowired这个注解,由我们的spring框架来进行处理,当spring框架读取到了这个注解之后,就会去IOC容器中去找userDao这个类的实例对象,将其注入进来。

注解的分类

按运行机制(注解存在于程序的那个阶段)将注解分为三类:源码注解(只在源码存在)、编译注解(在class文件中也存在)、运行时注解(在运行阶段仍然起作用)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
按照来源来分的话,有如下三类:
1:JDK自带的注解(Java目前只内置了三种标准注解:@Override、@Deprecated、@SuppressWarnings,以及四种元注解:@Target、@Retention、@Documented、@Inherited)
2:第三方的注解——这一类注解是我们接触最多和作用最大的一类
3:自定义注解——也可以看作是我们编写的注解,其他的都是他人编写注解

按照功能来分的,还有,元注解——注解的注解。
其实我们不用区分特意区分原生注解,元注解,自定义注解,第三方注解这些概念,我们需要知道的就是他们都是注解,用来提供一些信息,以便于被读取后进行处理的。分类都是基于一个角度进行区分的,分类不是重点。

学习如何使用注解

如何使用一个自定义注解?

使用案例
在java8之前如果我们要使用一个注解能够重复对某个类进行注解的实现方式。

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Validate {
    /*
     * @Description: String表示注解提供信息值的类型,bizCode表示变量标识符,只是变量标识符需要加上()。
     * @Author: zdonliu
     * @Date: 2022/9/26 3:29 下午
      * @param null
     **/
    String bizCode();


    String orderType();
    
}

上面的@validate注解,bizcode和orderType是一对一的关系,我希望可以添加如下的注解

@Validate(bizCode = "fruit",orderType = 1)
@Validate(bizCode = "fruit",orderType = 2)
@Validate(bizCode = "vegetable",orderType = 2)
public class BizLogic2 {
}

很抱歉在java8之前,这种方式不行,不过你可以这么做,新建一个如下的注解

@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Validates {
    Validate[] value();  //表明这个注解的值是Validate类型的一个数组,我们应该传一个注解
}

注意这个聚合注解默认约束value来存储子注解
然后修改代码为

//如果注解只有一个值,那么我们可以省略变量名,初始化一个注解时需要使用@加注解名才能表明这是一个注解,然后用()将其需要的值赋予即可
@Validates({@Validate(bizCode = "fruit",orderType = "1")})
public class BizLogic2 {
}

在java8的@Repeatable出来之后,我们在不改动@Validates的情况下,对@Validate进行修改,增加@Repeatable(Validates.class)

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Repeatable(Validates.class)
public @interface Validate {

    /**
     * 业务类型
     * @return
     */
    String bizCode();

    /**
     * 订单类型
     * @return
     */
    int orderType();

}

原理
那么@Repeatable的原理是啥?

语法糖而已!

我们编译下面代码

/*@Validates(value = {*/
        @Validate(bizCode = "fruit",orderType = 1)
        @Validate(bizCode = "fruit",orderType = 2)
        @Validate(bizCode = "vegetable",orderType = 2)
/*})*/
public class BizLogic2 {
}

发现编译成了
在这里插入图片描述
带默认值的注解,如果注解里面某个元素带默认值那么我们对注解初始化时可以不带这个参数。比如@version(major=1).

public  @interface  Version {
    int major();
    int minor() default 0; // zero as default value for minor
}

如何解析注解

使用注解完成一个简单的测试框架。
设计方案,注解一般同反射结合使用,完成此功能的方案如下,定义一个注解check,然后我们在我们需要测试的类的方法上添加上此注解。
然后在主方法中初始化一个计算器类,通过字节码获取类对象,然后获取所有方法,检查方法是否被使用check注解,如果被注解了,则使用invock方法执行此方法,将测试结果写入文件。
参考文章
框架基础–全面解析JAVA注解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值