//先定义一下接口
package testdynamic;
public interface Bank {
public void checkBalance();
public void checkInformation();
}
package testdynamic;
public class BankImp implements Bank{
@Override
public void checkBalance() {
System.out.println("你的帐户余额为200");
}
@Override
public void checkInformation() {
System.out.println("你是王明");
}
}
package testdynamic;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class BankProxy implements InvocationHandler{
/*BankProxy要实现InvocationHandler接口,该接口是JDK反射体系里的一个接口,它可以动态
* 调用目标对象的方法。
*
*
*/
private Object target; //需被代理的目标对象
public void setTarget(Object target) {
this.target = target;
}
/*
* Object invoke(Object proxy,
Method method,
Object[] args)
throws Throwable在代理实例上处理方法调用并返回结果。
在与方法关联的代理实例上调用方法时,将在调用处理程序上调用此方法。
参数:
proxy - 在其上调用方法的代理实例
method - 对应于在代理实例上调用的接口方法的 Method 实例。Method 对象的声明类将
是在其中声明方法的接口,该接口可以是代理类赖以继承方法的代理接口的超接口。
args - 包含传入代理实例上方法调用的参数值的对象数组,如果接口方法不使用参数,则
为 null。基本类型的参数被包装在适当基本包装器类(如 java.lang.Integer
或 java.lang.Boolean)的实例中。
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result=null;
if(method.getName().equals("checkBalance"))
{
System.out.println("aaa"); //这个位置可以换为拦截器的方法
result=method.invoke(target, args);
System.out.println("bbb"); //也可以换为拦截器的方法
}
else
result=method.invoke(target, args);
return result;
}
/*Proxy.newProxyInstance()方法根据接口数组动态创建代理实例,创建的代理类是JVM在内
* 在内存中动态创建,该类实现传入参数里接口数组中的全部接口。因此,动态代理要求被代理
* 的必须 是接口的实现类,否则无法为其构造相应的动态实例。
*
* (getProxy()方法也可以单独封装为一个代理工厂类即ProxyFactory类)
*/
public Object getProxy(Object obj)
{
this.setTarget(obj);
return Proxy.newProxyInstance(BankImp.class.getClassLoader(),
obj.getClass().getInterfaces(),this);
}
}
package testdynamic;
public class DynamicTest {
public static void main(String[] args)
{
Bank targetBank=new BankImp(); //实现接口的实例将作为代理的目标对象
Bank bank=null;
//Object proxy=ProxyFactory.getProxy(targetBank);
Object proxy=new BankProxy().getProxy(targetBank);
if(proxy instanceof Bank)
bank=(Bank)proxy;
bank.checkBalance();
bank.checkInformation();
}
}