Spring注解原理

复习Annotation
注意:注解不同于注释。

注释是给开发人员看的,没有任何功能
注解是给框架/软件看的,可以赋予注解一些功能
元注解
元注解:由JDK提供的,用于限制/修饰自定义注解的注解。常见有的2个:
@Target:用来限制自定义注解可以用在什么地方。从ElementType里取值的,常用值有:
ElementType.TYPE:可以用在类、接口上
ElementType.METHOD:可以用在方法上
ElementType.FIELD:可以用在字段(成员变量)上
@Retention:用来限制自定义注解保留到什么阶段(生命周期)。从RetentionPolicy里取值,常用的:
RetentionPolicy.SOURCE:保留到源码阶段
RetentionPolicy.CLASS:保留到字节码阶段
RetentionPolicy.RUNTIME:保留到运行阶段
注解的属性
注解的属性,并非所有类型都可以。只支持:

8种基本数据类型
String类型
Class类型
注解类型
枚举类型:enum
以及以上类型的一维数组形式
自定义注解示例
@Target({ElementType.METHOD, ElementType.FIELD})//可以用在方法上、字段上
@Retention(RetentionPolicy.RUNTIME)//保留到运行阶段
public @interface MyAnno {

    String value() default "default value";

    String[] abc() default "abc";

}
1
2
3
4
5
6
7
8
9
使用注解
public class Demo02MyAnnoTest {

    //不给属性赋值,所有属性使用默认值
    @MyAnno 
    private String str1;
    
    //给abc属性赋值aaaa,value属性不赋值(使用默认值)
    @MyAnno(abc="aaaa")
    private String str2;

    //给value属性赋值,abc属性不赋值(使用默认值)。只给value赋值,可以省略"value="不写
    @MyAnno("value的值")
    private String str3;
    
    //给abc和value两个属性都赋值
    @MyAnno(abc = "aaaa", value = "value的值")
    private String str4;
    
    @MyAnno(value = "VALUE1", abc = "abcabc")
    public void show(){
        System.out.println("======show()======");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
为什么要解析注解
注解本身是没有任何功能的,仅仅是相当于一个记号(标记)。
把注解(记号)标记在某个类上或方法上,在使用反射调用时,可以根据注解上是否有注解,来增加不同的功能代码
解析注解
public class DemoMyAnnoParseTest {

    @MyAnno(value = "VALUE1", abc = "abcabc")
    public void show(){
        System.out.println("======show()======");
    }

    //如果show方法上有MyAnno注解,并且value值值是"VALUE",则执行show方法;否则不执行
    public static void main(String[] args) throws Exception {
        DemoMyAnnoParseTest demo = new DemoMyAnnoParseTest();

        Class clazz = demo.getClass();
        Method method = clazz.getMethod("show");

        //判断方法上是否有MyAnno注解
        boolean b = method.isAnnotationPresent(MyAnno.class);
        if (b) {
            //获取方法配置的注解对象
            MyAnno myAnno = method.getAnnotation(MyAnno.class);
            String value = myAnno.value();
            String[] abc = myAnno.abc();

            //判断:如果value值是  VALUE,就执行这个方法,否则不执行
            if ("VALUE".equals(value)) {
                method.invoke(demo);
            }
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
注解原理
注解是给框架/软件看的,可以赋予注解一些功能**

一个注解准确意义上来说,只不过是一种特殊的注释而已,如果没有解析它的代码,它可能连注释都不如。

所以,当我们在SpringMVC里使用注解时,框架会扫描注解,通过反射方法读出注解,然后执行对应的方法。

总结
首先,我们通过键值对的形式可以为注解属性赋值,像这样:@Hello(value = “hello”)。

接着,你用注解修饰某个元素,编译器将在编译期扫描每个类或者方法上的注解,会做一个基本的检查,你的这个注解是否允许作用在当前位置,最后会将注解信息写入元素的属性表。

然后,当你进行反射的时候,虚拟机将所有生命周期在 RUNTIME 的注解取出来放到一个 map 中,并创建一个 AnnotationInvocationHandler 实例,把这个 map 传递给它。

最后,虚拟机将采用 JDK 动态代理机制生成一个目标注解的代理类,并初始化好处理器。

那么这样,一个注解的实例就创建出来了,它本质上就是一个代理类,你应当去理解好 AnnotationInvocationHandler 中 invoke 方法的实现逻辑,这是核心。一句话概括就是,通过方法名返回注解属性值。

注解原理详解:https://www.baidu.com/link?url=dTc8pBUzTVVFP0ZYQnhNpIKOCDFRasGZWX73swVDHSnopqX4ndGFalecJTaXe3_snwpcPcWSjpGj_PsLVt0pYa&wd=&eqid=c9b072730003858d000000065e09fa74
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值