动态代理
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
动态代理
简单介绍
代理可分为静态代理和动态代理。静态代理在源代码级实现,而动态代理在运行时实现。
代理的几个概念:
抽象角色:声明真实对象和代理对象的共同接口。(就是接口)
代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。(就是实现上述接口的代理,即代理对象)真实角色:代理角色所代表的真实对象,是我们最终要引用的对象。(就是要代理的真正对象,即被代理对象,或称目标对象)
在使用JDK中的动态代理时,要注意目标对象必须实现接口。动态代理的几个概念:
动态代理类:实现了一系列的接口,而这些接口是在动态代理类被创建时指定的。
代理接口:就是由动态代理类所实现的接口。
代理实例:就是动态代理类的实例。
动态代理类和其实例可以由ng.reflect.Proxy来创建。如要创造接口Foo的代理:
InvocationHandler handler = new MyInvocationHandler(...);
//创建动态代理类
Class proxyClass = Proxy.getProxyClass(
Foo.class.getClassLoader(), new Class[] { Foo.class });
//创建动态代理类的实例
Foo f = (Foo) proxyClass.
getConstructor(new Class[] { InvocationHandler.class }).
newInstance(new Object[] { handler });
或者使用(更简单,一步完成创建动态代理类的实现):
Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
new Class[] { Foo.class },
handler);
实例演示
DynamicProxy.java
package com.lwj.proxy;
import ng.reflect.InvocationHandler;
import ng.reflect.Method;
import ng.reflect.Proxy;
/*
* DynamicProxy有两个作用:
* 一是创建动态代理实例;
* 二是负责实现InvocationHandler接口,即负责调用真实对象的方法。
*/
public class DynamicProxy implements InvocationHandler {
private Object targetObject;//这就是真实对象,即被代理的目标对象
public DynamicProxy(Object targetObject) {
super();
this.targetObject = targetObject;
}
/*
* 用JDK中的Proxy的newProxyInstance方法创建动态代理实例
* 该方法有三个参数:
* ClassLoader loader——真实对象的ClassLoader(类加载器)
* Class>[] interfaces——真实对象实现的接口(在这指定代理接口)
* InvocationHandler h——要调用真实对象方法的处理器,本例中,由DynamicProxy负责 * 返回值就是动态的代理对象
*/
public static Object create(Object targetObject) {
return
Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
targetObject.getClass().getInterfaces(), new
DynamicProxy(targetObject));
}
/*
* invoke就是InvocationHandler接口的方法。
* 当代理对象调用真实对象的方法时,内部通过invoke实现。
* 该方法接收三个参数(在调用真实对象的方法时由系统填入):
* Object proxy——动态代理实例
* Method method——调用的真实对象的方法名
* Object[] args———调用的真实对象的方法参数
* 该方法返回调用结果
* 另外,这里在调用真实对象的方法前,打印两行信息——这也是AOP(面向切面编程)的基本原理
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("调用
"+method.getDeclaringClass().getName()+":"+method.getName());
Object obj=method.invoke(targetObject, args);
System.out.println("调用结束!");
return obj;
}
}
ProxyTest.java
package com.lwj.proxy;
import java.util.ArrayList;
import java.util.List;
public class ProxyTest {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
List
/*
* 创建一个动态代理对象,以代理ArrayList
* 它们共同实现List
*/
list = (List
/*
* 以下三个方法执行时,系统将调用DynamicProxy对象的invoke方法
*/
list.add("Hello,world!");
list.remove(0);
list.add(0, "Hi!");
}
}