【Java-Reflection】动态代理
2016-02-20 10:52
316 查看
一、静态代理
首先先了解一下静态代理:interface Subject{ public void print(String s); } class RealSubject implements Subject{ public void print(String s){ System.out.println(s+"1"); } } class Proxy implements Subject{ private Subject subject; public Proxy(Subject subject){ this.subject=subject; } public void print(String s){ //do something before subject.print(s); //do something after } }Client 测试
public static void main(String[] args) { RealSubject realSubject = new RealSubject(); Proxy proxy = new Proxy(realSubject1); proxy.print("this is static proxy "); }个人理解:说白了,实际类和代理类同时实现了某个抽象的接口。实际调用的时候,调用代理类的方法,代理类内部有实际类的成员,代理类把请求转发给实际类执行。
二、动态代理
话不多说,先上代码:public class DynamicProxy { public static void main(String[] args) { RealSubject realSubject = new RealSubject(); //第一个参数是类加载器,第二个参数是接口 Subject proxySubject = (Subject) Proxy.newProxyInstance( Subject.class.getClassLoader(), //realSubject.getClass().getClassLoader(), new Class[]{Subject.class},//realSubject.getClass().getInterfaces(), new ProxyHandler(realSubject)); proxySubject.print("this is a dynamic proxy"); } } interface Subject{ public void print(String s); } class RealSubject implements Subject{ public void print(String s){ System.out.println(s); } } class ProxyHandler implements InvocationHandler{ private Object proxied; public ProxyHandler(Object o) { proxied = o; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result; result = method.invoke(proxied, args); return result; } }和静态最大的区别,用了反射实现了代理。
实际类:
同样,有一个抽象接口和实现了该接口的实际类。
代理处理类:
但是代理类不用实现这个接口,然是实现了InvocationHandler接口,里面仅有invoke方法。同样,代理类内部还是得有一个Object对象,也就是被代理的类(可以通过代理类的构造器传入)。然后invoke中必要的代码就是
Object result; result = method.invoke(proxied, args); return result;在前后可以根据自己需求添加额外的功能。
client测试:
用Proxy.newProxyInstance返回一个接口类型的代理实体,后续只要调用这个代理实体就可以传请求给实际的功能类。
newProxyInstance()里面的三个参数:1.类加载器 2.接口class 3.代理处理类
三、动态代理优势
静态代理中,实际功能类和代理类是一一对应的,他们都实现了同样的功能接口。但是动态代理则不是,上代码
public class DynamicProxy {
public static void main(String[] args) {
RealSubject realSubject = new RealSubject();
//第一个参数是类加载器,第二个参数是接口
Subject proxySubject = (Subject) Proxy.newProxyInstance(
Subject.class.getClassLoader(), //realSubject.getClass().getClassLoader(),
new Class[]{Subject.class},//realSubject.getClass().getInterfaces(),
new ProxyHandler(realSubject));
proxySubject.print("this is a dynamic proxy");
//代理第二个类
RealSayHello realSayHello = new RealSayHello();
SayHello helloProxy = (SayHello)Proxy.newProxyInstance(
realSayHello.getClass().getClassLoader(),
realSayHello.getClass().getInterfaces(),
new ProxyHandler(realSayHello));
helloProxy.say();
}
}
interface Subject{
public void print(String s);
}
class RealSubject implements Subject{
public void print(String s){
System.out.println(s);
}
}
interface SayHello{
public void say();
}
class RealSayHello implements SayHello{
public void say() {
System.out.println("real:hello!");
}
}
class ProxyHandler implements InvocationHandler{
private Object proxied;
public ProxyHandler(Object o) {
proxied = o;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result; result = method.invoke(proxied, args); return result;
}
}
代码和上面的例子多了一个接口和实际功能类,但是代理处理类ProxyHandler不用改变,也不用增加。
动态代理中,实现了InvocationHandler的类仅仅只是一个处理代理类的类,他并不和实际功能类一一对应,可以根据不用的实际类通过这个Handler生成对应的代理类。
相关文章推荐
- java,基本数据类型
- JAVA多线程-对象及变量的并发访问(二)volatile关键字
- 4个理由告诉你Java为何排行第一
- 4个理由告诉你Java为何排行第一
- 【JAVA】 基础练习 BASIC-6 杨辉三角形
- Struts2--Global Result全局结果集
- Java初学之IO(一)
- Struts2--Result类型
- 【转载】classpath、path、JAVA_HOME的作用及JAVA环境变量配置
- java 输入一个时间输出下一秒
- 最常用的15大Eclipse开发快捷键技巧
- Struts2--默认Action
- java Map及Map.Entry详解
- javacript 对象属性积累
- Struts2--模块包含
- Eclipse 与Android 模拟器断开连接
- eclipse 运行项目 无报错,保存数据时页面一直卡在Form页面上
- Java 入门 之 聊天室 服务器端源码
- 关于java开发环境的搭建
- java boolean类型占多少字节