26.注解、动态代理

目录

一.注解

1.1 注解概述

1.2 注解的作用

1.3 自定义注解

1.3.1 什么是自定义注解

1.3.2 自定义注解格式

1.4 元注解

1.4.1 什么是元注解

1.4.2 种类

1.5 注解解析

1.5.1 什么是注解解析

1.5.2 相关接口

1.5.3 解析注解的技巧

1.5.4 案例

二.动态代理

2.1 什么是动态代理

2.2 步骤

2.3 动态代理的优点

2.4 代码示例


一.注解

1.1 注解概述

Java注解又称Java标注,是 JDK5.0 引入的一种注释机制。Java语言中的类、构造器、成员变量、成员方法、参数都可以被注解标注。

1.2 注解的作用

对Java中类、方法、成员变量做标记,然后进行特殊处理,至于到底做何种处理由业务需求来决定。

例如:JUnit 框架中,标记了注解 @Test 的方法就可以被当成测试方法执行,而没有标记的就不能当成测试方法执行。

1.3 自定义注解

1.3.1 什么是自定义注解

自定义注解就是自己做一个注解来使用

1.3.2 自定义注解格式

代码示例:

public @interface Book{

        String value();

        int age() default 11;

}

注意事项

  • value是特殊属性,如果只有一个value属性的情况下,注解中的value名称可以省略不写
  • 但是如果有多个属性,并且除value之外的其它属性没有默认值,那么value属性的名称是不能省略的

1.4 元注解

1.4.1 什么是元注解

用来对注解进行注解的注解叫做元注解

1.4.2 种类

常见的元注解如 @Target、@Retention、@Documented、@Inherited

1.@Target:约束自定义注解只能在哪些地方使用。@Target中可使用的值定义在 ElementType 枚举类中,常用值如下:

  • TYPE:类,接口
  • FIELD:成员变量
  • METHOD:成员方法
  • PARAMETER:方法参数
  • CONSTRUCTOR:构造器
  • LOCAL_VARIABLE:局部变量

2.@Retention:申明注解的生命周期。@Retention中可使用的值定义在 RetentionPolicy 枚举类中,常用值如下:

  • SOURCE: 注解只作用在源码阶段,生成的字节码文件中不存在
  • CLASS:  注解作用在源码阶段,字节码文件阶段,运行阶段不存在,默认值.
  • RUNTIME:注解作用在源码阶段,字节码文件阶段,运行阶段(开发常用)

3.@Documented:描述在使用javadoc工具为类生成帮助文档时是否要保留其注解信息

4.@Inherited:被他修饰的注解具有继承性。如果某个类使用了被@Inherited修饰的注解,则其子类将自动具有该注解。

例子:

首先创建一个注解 MyInheritedAnnotation,并用元注解@Inherited修饰这个注解

@Inherited
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyInheritedAnnotation {

    public String name() default "pengjunlee";

}

创建一个父类 Parent,并用 @MyInheritedAnnotation 注解修饰这个类

@MyInheritedAnnotation(name = "parent")
public class Parent {
}

创建一个子类 Child 继承父类 Parent,在子类中编写代码查看是否能够获取父类注解@MyInheritedAnnotation中的属性

public class Child extends Parent {

    public static void main(String[] args) {
        Class<Child> child = Child.class;
        MyInheritedAnnotation annotation = child.getAnnotation(MyInheritedAnnotation.class);
        System.out.println(annotation.name());
    }

}

最后得到一个输出:parent。证明子类确实能够继承父类的注解

1.5 注解解析

1.5.1 什么是注解解析

注解的操作中经常需要进行解析,注解的解析就是判断是否存在注解,如果存在就解析出内容。

1.5.2 相关接口

Annotation: 注解的顶级接口,注解都Annotation类型的对象(自定义注解默认实现Annotation)

AnnotatedElement:该接口定义了与注解解析相关的解析方法

注意:

所有的类成分Class,Method,Field,Constructor,都实现了AnnotatedElement接口,他们都拥有解析注解的能力。

1.5.3 解析注解的技巧

  • 注解在哪个成分上,我们就先拿哪个成分对象
  • 比如注解作用成员方法,则要获得该成员方法对应的Method对象,再来拿上面的注解
  • 比如注解作用在类上,则要该类的Class对象,再来拿上面的注解
  • 比如注解作用在成员变量上,则要获得该成员变量对应的Field对象,再来拿上面的注解

1.5.4 案例

案例一

注解代码:

被注解标注的代码:

解析代码:

案例二:模拟Junit框架

需求:定义若干个方法,只要加了MyTest注解,就可以在启动时被触发执行

分析:

  • 定义若干个方法,只要有@MyTest注解的方法就能在启动时被触发执行,没有这个注解的方法不能执行
  • 定义一个自定义注解MyTest,只能注解方法,存活范围是一直都在。

注解代码:

测试代码:

二.动态代理

2.1 什么是动态代理

代理就是被代理者没有能力或者不愿意去完成某件事,需要找个人代替自己去完成这件事,动态代理就是用来对业务功能进行代理的。

2.2 步骤

  1. 创建一个接口
  2. 创建一个实现类要实现接口,代理通常是基于接口实现的
  3. 创建代理类
  4. 创建测试类进行测试

2.3 动态代理的优点

  • 非常的灵活,支持任意接口类型的实现类对象做代理,也可以直接为接本身做代理。
  • 可以为被代理对象的所有方法做代理。
  • 可以在不改变方法源码的情况下,实现对方法功能的增强。(重要)
  • 不仅简化了编程工作、提高了软件系统的可扩展性,同时也提高了开发效率。

2.4 代码示例

由于代码太多,这里只放代理类的代码

代理类:

public class MyProxy {
    //通过一个静态方法,为用户业务对象返回一个代理对象
    public static <T> T getProxy(T obj){
        /**
         * 第一个参数:为代理对象设置类加载器,类加载器会将代理类加载到内存中,代理对象会根据代理类创建
         * 第二个参数:设置代理对象需要继承的接口
         * 第三个参数:设置被代理对象要增强的功能
         */
        return (T)Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), new InvocationHandler() {
            /**
             *
             * @param proxy:用户业务类的类对象
             * @param method:用户业务类的对象方法
             * @param args:用户业务类的对象方法需要的参数
             * @return
             * @throws Throwable
             */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                long startTime = System.currentTimeMillis();
                Object o = method.invoke(obj,args);
                long enTime = System.currentTimeMillis();
                System.out.println("该方法花费时间位"+(enTime-startTime)/1000.0+"s");
                return o;
            }
        });
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

真滴book理喻

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值