在不改变原有类的请情况下,为类扩展功能
普通方法手写代理对象在每个方法中添加麻烦synchronized 关键字,调用代理目标功能的方法,费时费力。容易出错
public class ProxyList使用动态代理方法生成代理对象:Proxyimplements List { //初始化目标对象,防治返回空值 private List target; @Override public synchronized boolean add(E e) { //执行的是目标方法 return target. add(e); } @Override public synchronized boolean remove(Object o) { //执行的是目标方法 return target.remove(o); } ..... }
生成一个线程安全的代理对象的方法:
Proxy.newProxyInstance(Foo.class.getClassLoader()类加载器,
new class[] {Foo.class} 实现的接口,
handler 调用处理器);
动态代理对象最终实现的还被是代理目标上的方法,调用处理器就是干这个活的
handler 调用处理器实现了InvocationHandler接口的API,
动态代理类,是一个实现在创建类的时候运行时指定的接口列表的类,
代理接口是代理类实现的一个接口。代理实例时代理类的一个实例。每个代理实例都有一个关联的调用处理程序对象,它可以实现接口InvocationHandler。通过其中一个代理接口的代理实例上的方法调用将被指派到实例的调用处理程序的Invoke方法。并传递代理实例,识别调用方法的java.lan.reflect.Method对象以及包含参数的Object类型的数组,调用处理程序以适当的方式处理编码的方法调用,并且它返回的结果将作为代理实例额上方法调用的结果返回。
方法摘要:invoke(object proxy(代理的对象),Method method(调用的方法), object[] args传递的参数){
Object value = null;
synchronized(proxy){
value = method.invoke(target,args)
}
return value;
}
当有线程发起调用时,都会执行调用处理器的同一个方法invoke
项目测试//第一步,使用动态代理方法生成代理对象:Proxy
public class ProxyLisy {
public static void main(String[] args) {
//产生一个List的代理对象list
//Proxy.newProxyInstance,产生代理对象的方法
List list = (List) Proxy.newProxyInstance(
//固定写法,代理对象所在的类加载器
ProxyLisy.class.getClassLoader(),
//被代理接口对象,你要代理的对象接口,必须是接口!!!
new Class[]{List.class},
//调用处理器,执行代理目标方法的部分(括号中的是代理的对象)
//这里调用的是构造方法,不是类,是接口的下的类
new ProxyListHandler<>(new ArrayList<>()));
//为定义的代理对象添加内容
list.add("sayhi");
list.add("inory");
list.add("sayhitolover");
//获取代理对象中的内容
String s = list.get(1);
System.out.println(s);
System.out.println(list);
}
}
//第二步,实现InvocationHandler接口的invoke方法。创建对应的调用处理器
//handler 调用处理器的创建,动态代理对象最终实现的还被是代理目标上的方法
class ProxyListHandler implements InvocationHandler{
//创建默认的被代理的对象
private Object target;
//创建构造方法
public ProxyListHandler(Object target){
this.target = target;
}
//重写invoke方法
@Override
public Object invoke(Object proxy,//动态生成的代理对象
Method method, //被调用的方法
Object[] args//传递到方法中的参数
) throws Throwable {
Object value = null;
//使用同步块进行加锁
synchronized (this) {
System.out.println("正在执行" + method);
System.out.println("传递参数" + args);
value = method.invoke(target, args);
//value是方法的返回值
System.out.println("方法返回值" + value);
}
return value;
}
}



