(九)Spring核心框架 - AOP之动态代理机制
2015-02-09 17:28
459 查看
动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码。动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java 反射机制可以生成任意类型的动态代理类。
一.相关类及其方法:
java.lang.reflect.Proxy,
Proxy 提供用于创建动态代理类和实例的静态方法.
newProxyInstance()返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序
java.lang.reflect.InvocationHandler,
InvocationHandler 是代理实例的调用处理程序实现的接口。
invoke()在代理实例上处理方法调用并返回结果。在与方法关联的代理实例上调用方法时,将在调用处理程序上调用此方法。
具体实例:联谊会或者相亲
1、寻找GF接口
2、寻找GF实现类
3、代理类处理
4、动态代理实现
到此,上面是整个动态代理的过程。
二、动态代理步骤总结
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))。
三、附录$Proxy0类的源码
一.相关类及其方法:
java.lang.reflect.Proxy,
Proxy 提供用于创建动态代理类和实例的静态方法.
newProxyInstance()返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序
java.lang.reflect.InvocationHandler,
InvocationHandler 是代理实例的调用处理程序实现的接口。
invoke()在代理实例上处理方法调用并返回结果。在与方法关联的代理实例上调用方法时,将在调用处理程序上调用此方法。
具体实例:联谊会或者相亲
1、寻找GF接口
package com.aop; /** * 寻找GF接口 * * @author Anndy */ public interface FindGFInterface { /** * 寻找GF方法 */ public void findGF(); }
2、寻找GF实现类
package com.aop; /** * Anndy寻找GF实现类 * * @author Anndy */ public class AnndyFindGFInterfaceImpl implements FindGFInterface { public void findGF() { System.out.println("Anndy go to find GF!"); } }
3、代理类处理
package com.aop; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; /** * 打扮帅点,去约会 * * @author Anndy */ public class ReadyInvocationHandler implements InvocationHandler { private Object anndy = null; public ReadyInvocationHandler(Object realSubject) { this.anndy = realSubject; } /** * 动态代理类$Proxy0调用FindGF方法时会调用它自己的FindGF方法, * 而它自己的FindGF方法里面调用的是super.h.invoke(this, , ),也就是父类Proxy的h的invoke方法, * 实际上就是ReadyInvocationHandler类的invoke方法。 所以invoke(Object proxy, Method * m,Object[] args)中的proxy实际上就是动态代理类$Proxy0, * 在这里不能将其强转成AnndyFindGFInterfaceImpl然后调用它的FindGF方法,会出现死循环 */ public Object invoke(Object proxy, Method m, Object[] args) { Object result = null; try { System.out.println(proxy.getClass().getSimpleName()); System.out.println("Anndy找女朋友,代理人给他打扮了打扮。"); result = m.invoke(anndy, args); } catch (Exception ex) { System.exit(1); } return result; } }
4、动态代理实现
package com.aop; import java.lang.reflect.Proxy; /** * 联谊会现场 * * @author Anndy */ public class SceneOfSodality { public static void main(String args[]) { /** * 得到AnndyFindGFInterfaceImpl这个类的一个代理类, * 同时为代理类绑定了一个处理类ReadyInvocationHandler。 * 每次调用AnndyFindGFInterfaceImpl这个子类的findGF方法时, * 并不是anndy这个AnndyFindGFInterfaceImpl类的实例去调用, * 而是这个AnndyFindGFInterfaceImpl的代理类ReadyInvocationHandler去调用它自己的invoke方法 */ // 实例化对象 FindGFInterface anndy = new AnndyFindGFInterfaceImpl(); /** * java中的动态代理实现 第一步,我们要有一个接口,还要有一个接口的实现类,而这个实现类就是我们要代理的对象, * 所谓代理就是在调用实现类的方法时,可以在方法执行前后做额外的工作,这个就是代理。 * 第二步,我们要自己写一个在代理类的方法执行时,能够做额外工作的类,而这个类必须继承InvocationHandler接口, * 因为代理类的实例在调用实现类的方法的时候,不会调真正的实现类的这个方法, * 而是转而调用这个类的invoke方法(继承时必须实现的方法),在这个方法中你可以调用真正的实现类的这个方法。 * 第三步,在要用代理类的实例去调用实现类的方法的时候,写出下面两段代码。 */ FindGFInterface proxy = (FindGFInterface) Proxy.newProxyInstance(anndy .getClass().getClassLoader(), anndy.getClass().getInterfaces(), new ReadyInvocationHandler(anndy)); proxy.findGF(); } }
到此,上面是整个动态代理的过程。
二、动态代理步骤总结
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))。
三、附录$Proxy0类的源码
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.lang.reflect.UndeclaredThrowableException; public final class $Proxy0 extends Proxy implements Manager { private static Method m1; private static Method m0; private static Method m3; private static Method m2; static { try { m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") }); m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]); m3 = Class.forName("com.ml.test.Manager").getMethod("modify", new Class[0]); m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]); } catch (NoSuchMethodException nosuchmethodexception) { throw new NoSuchMethodError(nosuchmethodexception.getMessage()); } catch (ClassNotFoundException classnotfoundexception) { throw new NoClassDefFoundError(classnotfoundexception.getMessage()); } } public $Proxy0(InvocationHandler invocationhandler) { super(invocationhandler); } @Override public final boolean equals(Object obj) { try { return ((Boolean) super.h.invoke(this, m1, new Object[] { obj })) .booleanValue(); } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } @Override public final int hashCode() { try { return ((Integer) super.h.invoke(this, m0, null)).intValue(); } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } public final void modify() { try { super.h.invoke(this, m3, null); return; } catch (Error e) { } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } @Override public final String toString() { try { return (String) super.h.invoke(this, m2, null); } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } }
相关文章推荐
- Spring核心框架 - AOP之动态代理机制
- Java基础---Java---基础加强---类加载器、委托机制、AOP、 动态代理技术、让动态生成的类成为目标类的代理、实现Spring可配置的AOP框架
- 动态代理,Spring两大核心知识BeanFactory、AOP框架!
- Java基础---Java---基础加强---类加载器、委托机制、AOP、 动态代理技术、让动态生成的类成为目标类的代理、实现Spring可配置的AOP框架
- Spring AOP中的动态代理实现机制
- 黑马程序员--09.动态与代理AOP--06【动态代理实例化的过程升级--目标对象+系统功能的参数化】【实现类似Spring的可配置AOP框架】
- Spring3核心技术之AOP动态代理
- 基础加强____【动态代理 & AOP】【实现类Spring的AOP框架】
- Spring AOP——java的动态代理机制详解
- cglib动态代理例子和浅剖Spring Aop机制
- spring->aop中proxy-target-class属性的含义以及动态代理机制
- 框架 day37 Spring3,AOP,代理模式(动态/CGLIB/工厂bean),传统AOP,AspectJ框架(基于xml/注解),切入点表达式,jdbcTemplate
- SSH与SSM学习之Spring14——动态代理之自己的AOP框架
- Spring AOP中的动态代理机制
- Spring AOP 代理实现的两种方式: JDK动态代理 和 Cglib框架动态代理
- Spring AOP的实现——动态代理机制
- Spring AOP原理——Java中的动态代理机制
- Spring—AOP两种代理机制对比(JDK和CGLib动态代理)
- Spring AOP 动态代理机制
- Spring AOP的实现机制(一)----- 动态代理