------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------
JAVA的动态代理
代理模式
代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。
按照代理的创建时期,代理类可以分为两种。
静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了,所以静态代理是使用硬编码的方式实现的,这在开发中并不适用。
动态代理:在程序运行时,运用反射机制动态创建而成。 通俗点讲就是在运行时由配置文件决定要运行哪个类。
可以i加系统功能的位置:
1.在调用目标方法之前
2.在调用目标方法之后
3.在调用目标方法前后
4.在处理目标方法异常的catch块中
说先说一下静态代理:
package com.itheima;
//代理类和目标类的公共接口
interface MyInter {
public void method();
}
// 委托类
class Target implements MyInter {
public void method() {
System.out.println("Target...method");
}
}
// 静态代理类实现和委托类同样的接口
class ProxyBsc implements MyInter {
// 接口的对象
private MyInter b;
//将为委托类作为参数传递进来
public ProxyBsc(MyInter b) {
this.b = b;
}
public void method() {
//在这里可以写要增加的功能。
//System.out.println("Target...method");
//在这里也能写要增加的功能。
}
}
// 生成静态代理工厂,客户并不知道返回的是代理类对象还是委托类对象
class MyInterStaicFactory {
public static MyInter getInstance() {
// 返回代理类对象
return new ProxyBsc(new Target());
}
}
// 客户类
public class Client {
public static void main(String[] args) {
MyInter MyInter = MyInterStaicFactory.getInstance();
MyInter.method();
}
}
下面来看动态代理:
package com.itheima;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collection;
public class ProxyDemo {
public static void main(String[] args) throws Exception {
// 指定一个接口的类加载器和字节码获得代理类的字节码
Class clazzProxy = Proxy.getProxyClass(
Collection.class.getClassLoader(), Collection.class);
// 获得全部的构造方法
Constructor cons[] = clazzProxy.getConstructors();
// 查看全部的构造方法,从查看的结果得知有$Proxy0(InvocationHandler)的构造方法
for (Constructor clazzCons : cons) {
System.out.println(clazzCons);
}
Constructor con = clazzProxy.getConstructor(InvocationHandler.class);
// 实现了匿名内部类InvocationHandler
Collection proxy = (Collection) con
.newInstance(new InvocationHandler() {
// 代理要实现的类,即目标类
ArrayList array = new ArrayList();
@Override
public Object invoke(Object arg0, Method arg1, Object[] arg2)
throws Throwable {
// 记录开始时间
long startTime = System.currentTimeMillis();
// 传入参数并反射调用ArrayList的方法
Object obj = arg1.invoke(array, arg2);
// 记录方法结束时间
long endTime = System.currentTimeMillis();
// 调用方法耗时
System.out.println();
return null;
}
});
// 输出"null",因为可以调用toString()所以不是真正意义上的null.
System.out.println(proxy.toString());
proxy.add("你好");
proxy.add("中国");
System.out.println(proxy);
// 输出集合长度
System.out.println(proxy.size());
// clear()方法无返回值可以调用
proxy.clear();
}
}