java动态代理
啥都不说,先用代码说话
package com.thinkgem.jeesite.test; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * Created by Administrator on 2017/1/12 0012. */ public class invoke { public static void main(String[] args) { //代理类 Checkinvoke checkinvoke = new Checkinvoke(); //被代理类的实例 Settle settle = (Settle)checkinvoke.newProxy(new settteImpl()) ; Checkinvoke ttt = new Checkinvoke(); settle.calc(); settle.updatefund(); } public interface Settle{ public void calc(); public void updatefund(); } public static class settteImpl implements Settle{ @Override public void calc() { System.out.println("计算了"); } @Override public void updatefund() { System.out.println("更新资金了"); } } public static class Checkinvoke implements InvocationHandler{ private Object targetObject; public Object newProxy(Object targetObject){ this.targetObject = targetObject; return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),targetObject.getClass().getInterfaces(),this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if("calc".equals(method.getName())){ check(); }else{ System.out.println("bucheckt"); } /* * before :doSomething(); */ Object res = method.invoke(this.targetObject,args); /* * after : doSomething(); */ System.out.println("结束啦"); return res; } public void check() { System.out.println("检查了"); } } }
执行结果
检查了
计算了
结束啦
bucheckt
更新资金了
结束啦
动态代理创建对象过程可分为以下四个步骤:
1、通过实现InvocationHandler接口创建自己的调用处理器 IvocationHandler handler = new InvocationHandlerImpl(...);
2、通过为Proxy类指定ClassLoader对象和一组interface创建动态代理类
Class clazz = Proxy.getProxyClass(classLoader,new Class[]{...});
3、通过反射机制获取动态代理类的构造函数,其参数类型是调用处理器接口类型
Constructor constructor = clazz.getConstructor(new Class[]{InvocationHandler.class});
4、通过构造函数创建代理类实例,此时需将调用处理器对象作为参数被传入
Interface Proxy = (Interface)constructor.newInstance(new Object[] (handler));
为了简化对象创建过程,Proxy类中的newInstance方法封装了2~4,只需两步即可完成代理对象的创建。
生成的ProxySubject继承Proxy类实现Subject接口,实现的Subject的方法实际调用处理器的invoke方法,而invoke方法利用反射调用的是被代理对象的的方法(Object result=method.invoke(proxied,args))
posted on 2017-01-12 22:50 zhuanagyan 阅读(343) 评论(0) 编辑 收藏 举报