黑马程序员——代理

来源:互联网 发布:青岛搜索引擎排名数据 编辑:程序博客网 时间:2024/05/31 19:13
------- android培训java培训、期待与您交流! ----------

动态代理技术可以动态的生成一段内部有一个被扩展类引用的代码,生成的类类似于用组合这种方式,并把它动态的编译成class文件,然后装载进jvm中执行。著名的框架Spring的核心技术之一aop就是使用的就是动态代理技术。

 Java中为动态代理提供了支持,用到了类Proxy用于产生代理,还有一个接口InvocationHandler,用于在被代理的类的方法前后加入处理逻辑,这个接口内部有一个invoke方法,invoke接受三个参数,

代理Proxy 基本概念

安全、事物、日志要贯穿到好多模块中,就是交叉业务

AOP面向方面编程

目标:要使交叉业务模块化,将切面代码移动到原始方法的周围
代理是实现AOP功能的核心和关键技术

JVM可以在运行期动态生成出类的字节码,这种动态生成的类往往被用作代理类,即动态代理类

1JVM生成的动态类必须实现一个或多个接口,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 stubClass 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 {@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {// TODO Auto-generated method stubreturn 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() {@Overridepublic Object invoke(Object proxy, Method method,Object[] args) throws Throwable {// TODO Auto-generated method stublong 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;}}