动态代理(Dynamic Proxy)是JDK5 提供的一种新特性。其特点在于在程序的运行时刻动态的创建出代理类及其对象,而不像我们使用静态代理时必须在编译之前定义好代理类。在运行时刻,框架帮我们动态的创建出一个实现了多个接口的代理类,每个代理类的对象都会和一个InvocationHandler接口的实现类相关联。当我们调用了代理对象所代理的接口中的方法的时候,这个调用的信息会被传递给InvocationHandler的invoke方法。在 invoke方法的参数中可以获取到代理对象、方法对应的Method对象和调用的实际参数(内部是通过反射来实现的)。 invoke方法的返回值被返回给使用者,至于返回什么值可以由自己来定义,这种做法实际上相当于对方法调用进行了AOP拦截。
创建动态代理的步骤如下:
1. 创建一个实现接口InvocationHandler的类,它必须实现invoke方法。
2. 创建被代理类以及接口
3. 通过Proxy的静态方法newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)创建一个代理
4. 通过代理来调用方法(此代理实现了被代理类的接口)
/**
* DynamicSubject.java
* dynamicproxy
*
* Function: 动态代理类, java.lang.reflect.Proxy 是运行时生成的Class,在生成它的时候你必须传递
* 一组Interfaces给它(多个接口),然后返回的对象就实现了这些接口,这个Proxy就是一个纯粹的Porxy,
* 所以我们必须提供一个InvocationHandler,由它来接替
*
* ver date author
* ──────────────────────────────────
* 2011-6-12 Leon
*
* Copyright (c) 2011, TNT All Rights Reserved.
*/
package dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* ClassName:DynamicSubject
* Function: TODO ADD FUNCTION
* 创建动态代理的步骤如下:
* 1. 创建一个实现接口InvocationHandler的类,它必须实现invoke方法。
* 2. 创建被代理类以及接口
* 3. 通过Proxy的静态方法newProxyInstance(ClassLoader loader,
* Class[] interfaces, InvocationHandler h)创建一个代理
* 4. 通过代理来调用方法(此代理实现了被代理类的接口)
*
*
* Reason: TODO ADD REASON
*
* @author Leon
* @version
* @since Ver 1.1
* @Date 2011-6-12
*/
public class DynamicProxy implements InvocationHandler {
private Object sub ;
public Object getSub() {
return sub;
}
public void setSub(Object sub) {
this.sub = sub;
}
public DynamicProxy(Object obj){
this.sub=obj;
}
//proxy是框架动态生成的代理类
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
Object result = null ;
System.out.println("before calling: " + method);
//此处是真正被代理的对象
result=method.invoke(sub, args);
System.out.println("after calling ...");
return result;
}
public static void main(String... args){
RealSubject realSubject = new RealSubject();
DynamicProxy dynamicProxy = new DynamicProxy(realSubject);
// InvocationHandler invocationHandler = dynamicProxy;
//动态生成一个代理对象,返回的对象既不是RealSubject实例也不是DynamicPorxy的实例,而是动态生成
//的一个实例 $prxoy0,它实现了realSubject.getClass().getInterfaces()这些接口
ISubject subject=(ISubject)Proxy.newProxyInstance(dynamicProxy.getClass().getClassLoader(),
realSubject.getClass().getInterfaces(),dynamicProxy);
//当调用这一句的时候,$proxy0就会调用上面传入的invocationHandler的invoke方法,所以上面的方法要传入invocationHandler。
System.out.println("--------------------------Porxy realSubject1 ------------------------------------");
subject.request();
String result=subject.test();
System.out.println("return by test method :" + result);
System.out.println("--------------------------Proxy realSubject2--------------------------------------");
dynamicProxy.setSub(new RealSubject2());
subject.request();
System.out.println("proxy generate by system is :"+subject.getClass());
}
}
interface ISubject {
public void request();
public String test();
}
class RealSubject implements ISubject {
@Override
public void request() {
// TODO Auto-generated method stub
System.out.println("From real subject...request method....");
}
@Override
public String test() {
// TODO Auto-generated method stub
String str ="From real subject.....test method.....";
return str ;
}
}
class RealSubject2 implements ISubject {
@Override
public void request() {
// TODO Auto-generated method stub
System.out.println("From real subject2...request method....");
}
@Override
public String test() {
// TODO Auto-generated method stub
System.out.println("From real subject2 .....test method.....");
return null ;
}
}