目录
一.注解
1.1 注解概述
1.2 注解的作用
1.3 自定义注解
1.3.1 什么是自定义注解
1.3.2 自定义注解格式
1.3.3 注意事项
1.3.4 代码示例
1.4 元注解
1.4.1 什么是元注解
1.4.2 种类
1.5 注解解析
1.5.1 什么是注解解析
1.5.2 相关接口
1.5.3 注意事项(重要)
1.5.4 解析注解的技巧
1.5.5 案例一
1.5.6 案例二
二.动态代理
2.1 什么是动态代理
2.2 步骤
2.3 动态代理的优点
2.4 代码示例
一.注解
1.1 注解概述
Java注解又称Java标注,是JDK5.0引入的一种注释机制。
Java语言中的类、构造器、成员变量、成员方法、参数都可以被注解标注。
1.2 注解的作用
对
J
ava
中类、方法、成员变量做标记,然后进行特殊处理
,至于到底做何种处理由业务需求来决定。
例如:
JUnit
框架中,标记了注解
@Test
的方法就可以被当成测试方法执行,而没有标记的就不能当成测试方法执行。
1.3 自定义注解
1.3.1 什么是自定义注解
自定义注解就是自己做一个注解来使用
1.3.2 自定义注解格式
1.3.3 注意事项
①value是特殊属性,如果只有一个value属性的情况下,注解中的value名称可以省略不写。
②但是如果有多个属性,且多个属性没有默认值,那么value属性的名称是不能省络的。
1.3.4 代码示例
1.4 元注解
1.4.1 什么是元注解
注解注解的注解
1.4.2 种类
元注解有二个
@Target:约束自定义注解只能在哪些地方使用
@Target
中
可使用的值定义在ElementType枚举类中,常用值如下:
TYPE,类,接口
FIELD, 成员变量
METHOD, 成员方法
PARAMETE
R, 方法参数
CONSTRUCTOR, 构造器
LOCAL_VARIABLE, 局部变量
@Retention:申明注解的生命周期
@Retention
中
可使用的值定义在RetentionPolicy枚举类中,常用值如下:
SOURCE: 注解只作用在源码阶段,生成的字节码文件中不存在
CLASS:
注解作用在源码阶段,字节码文件阶段,运行阶段不存在,默认值.
RUNTIME:注解作用在源码阶段,字节码文件阶段,运行阶段(开发常用)
1.5 注解解析
1.5.1 什么是注解解析
注解的操作中经常需要进行解析,注解的解析就是判断是否存在注解,如果存在就解析出内容。
1.5.2 相关接口
Annotation: 注解
的顶级接口,
注解都
是
Annotation
类型的
对象(自定义注解默认实现Annotation)
AnnotatedElement:该接口定义了与注解解析相关的解析方法
1.5.3 注意事项(重要)
所有的类成分Class, Method , Field , Constructor
,
都实现了AnnotatedElement接口他们都拥有解析注解的能力。
1.5.4 解析注解的技巧
注解在哪个成分上,我们就先拿哪个成分对象。
比如注解作用成员方法,则要获得该成员方法对应的Method对象,再来拿上面的注解
比如注解作用在类上,则要该类的Class对象,再来拿上面的注解
比如注解作用在成员变量上,则要获得该成员变量对应的Field对象,再来拿上面的注解
1.5.5 案例一
注解代码:
被注解标注的代码:
解析代码:
1.5.6 案例二
模拟Junit框架
需求:
定义若干个方法,只要加了
MyTest
注解,就可以在启动时被触发执行
分析:①
定义若干个方法,只要有
@MyTest
注解的方法就能在启动时被触发执行,没有这个注解的方法不能执行
②定义一个自定义注解
MyTest
,只能注解方法,存活范围是一直都在。
注解代码:
测试代码:
二.动态代理
2.1 什么是动态代理
代理就是被代理者没有能力或者不愿意去完成某件事,需要找个人代替自己去完成这件事,动态代理就是用来对业务功能进行代理的。
2.2 步骤
1.创建一个接口
2.创建一个实现类要实现接口(代理通常是基于接口实现的)
3.创建代理类
4.创建测试类进行测试
2.3 动态代理的优点
1. 非常的灵活,支持任意接口类型的实现类对象做代理,也可以直接为接本身做代理。
2. 可以为被代理对象的所有方法做代理。
3. 可以在不改变方法源码的情况下,实现对方法功能的增强。(重要)
4. 不仅简化了编程工作、提高了软件系统的可扩展性,同时也提高了开发效率。
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;
}
});
}
}