动态代理技术可以动态的生成一段内部有一个被扩展类引用的代码,生成的类类似于用组合这种方式,并把它动态的编译成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;
}
}