动态代理技术可以动态的生成一段内部有一个被扩展类引用的代码,生成的类类似于用组合这种方式,并把它动态的编译成class文件,然后装载进jvm中执行。著名的框架Spring的核心技术之一aop就是使用的就是动态代理技术。
Java中为动态代理提供了支持,用到了类Proxy用于产生代理,还有一个接口InvocationHandler,用于在被代理的类的方法前后加入处理逻辑,这个接口内部有一个invoke方法,invoke接受三个参数,
代理Proxy 基本概念
安全、事物、日志要贯穿到好多模块中,就是交叉业务
AOP面向方面编程
目标:要使交叉业务模块化,将切面代码移动到原始方法的周围
代理是实现AOP功能的核心和关键技术
JVM可以在运行期动态生成出类的字节码,这种动态生成的类往往被用作代理类,即动态代理类
1)JVM生成的动态类必须实现一个或多个接口,JVM生成的动态类只能用作具有相同接口的目标类的代
理
2)CGLIB库可以动态生成一个类的子类一个类的子类也可以用作该类的代理。,如果要为一个没有实现
接口的类生成动态代理类,那么可以使用CGLIB库
代理方法在系统代码位置
1)在调用模板方法之前
2)在调用模板方法之后
3)在调用模板方法之前后
4)在处理目标方法异常的catch块中
二、创建代理
InvocationHandler接口
创建实现Collection接口的动态类和查看其名称,分析Proxy.getProxyClass方法的各个参数
创建动态类的实例对象
1)用反射获得构造方法
2)编写一个简单的InvocationHandler类
3)调用构造方法创建动态类的实例对象,并编写的InvocationHandler类的实例对象穿进去
InvocationHandler的运行原理
创建某一接口 MyInterface的代理:
InvocationHandler handler = newMyInvocationHandler(...);
代理实例调用处理程序实现的接口,对代理实例调用方法时,将对方法调用进行编码并将其指
派到它的调用处理程序的 invoke方法
Class proxyClass = Proxy.getProxyClass(MyInterface.class.getClassLoader(), new Class[] { MyInterface .class });
得到接口代理类的类加载器,要接口数组(因为可能要加载的不是一个接口)
MyInterface myint = (MyInterface ) proxyClass.getConstructor(newClass[]{
InvocationHandler.class}).newInstance(new Object[] { handler });
创建代理的示例代码:
package lianxi; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.ArrayList; import java.util.Collection; public class proxytest { /** * @param args * @throws Exception * @throws SecurityException */ public static void main(String[] args) throws SecurityException, Exception { // TODO Auto-generated method stub Class clazz = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class); Constructor[] Constructors = clazz.getConstructors(); for (Constructor constructor : Constructors) { StringBuilder sb = new StringBuilder(); sb.append("("); Class[] paramclazzs = constructor.getParameterTypes(); for (Class paramclazz : paramclazzs) { sb.append(paramclazz.getName()); sb.append(","); } if (paramclazzs.length != 0) sb.deleteCharAt(sb.length() - 1); sb.append(")"); System.out.println(constructor.getName() + sb.toString()); } class myInvocationHandler implements InvocationHandler { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO Auto-generated method stub return null; } } final ArrayList Target = new ArrayList(); Collection coll1 = (Collection) getProxy(Target); coll1.add("123"); coll1.add("456"); coll1.add("ert"); // System.out.println(coll1); System.out.println(Target); /* * System.out.println("*************************************"); Method[] * methods=clazz.getMethods(); for(Method method:methods){ StringBuilder * sb=new StringBuilder(); sb.append("("); Class[] * paramclazzs=method.getParameterTypes(); for(Class * paramclazz:paramclazzs){ sb.append(paramclazz.getName()); * sb.append(","); } if(paramclazzs.length!=0) * sb.deleteCharAt(sb.length()-1); sb.append(")"); * System.out.println(method.getName()+sb.toString()); } */ } private static Object getProxy(final Object Target) { Object coll1 = Proxy.newProxyInstance(Target.getClass() .getClassLoader(), Target.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO Auto-generated method stub long starttime = System.currentTimeMillis(); if ("123".equals(args[0])) args[0] = "hello"; Object obj = method.invoke(Target, args); System.out.println("args:::" + args); // System.out.println("proxy:::"+proxy); long endtime = System.currentTimeMillis(); System.out.println(method + "....runtime..." + (endtime - starttime)); return obj; } }); return coll1; } }