java的动态代理
Posted 宇宙唯心
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java的动态代理相关的知识,希望对你有一定的参考价值。
一 前言
在学习spring时候我们知道spring两大思想是IoC和AOP,IoC的依赖注入就不用说了,而对于Spring的核心AOP来说,其底层原理其实就是java的动态代理机制。
在java的动态代理机制中,有两个重要的类或接口,一个是InvocationHandler(interface),一个是Proxy(class).
InvocationHandler:
每一个动态代理类都必须实现InvocationHandler这个接口,并且每个代理类的实例都关联到了一个handler。当我们通过代理对象调用一个方法的时候,这个方法的调用就会被转发为由InvocationHandler这个接口的 invoke 方法来进行调用
Object invoke(Object proxy, Method method, Object[] args) throws Throwable proxy: 指代我们所代理的那个真实对象 method: 指代的是我们所要调用真实对象的某个方法的Method对象 args: 指代的是调用真实对象某个方法时接受的参数
Proxy:
Proxy这个类的作用就是用来动态创建一个代理对象的类,它提供了许多的方法,但是我们用的最多的就是 newProxyInstance 这个方法:
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException loader: 一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载 interfaces: 一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了 h: 一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上
二 实例说明
接口:
public interface SubjectProvider { String getSubject(String prefix); }
实现类1:
public class QmqSubjectProvider implements SubjectProvider { @Override public String getSubject(String prefix) { return prefix + " qmqSubject"; } }
实现类2:
public class QconfigSubjectProvider implements SubjectProvider { @Override public String getSubject(String prefix) { return prefix + " qconfigSubject"; } }
代理类模版:
public class ProxyHandler implements InvocationHandler { private Object target; public Object bind(Object target) { this.target = target; System.out.println("----" + target.getClass().getName()); System.out.println("----" + target.getClass().getInterfaces()[0]); return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { beforeMethod(); return method.invoke(target, args); } private void beforeMethod() { System.out.println("before method..."); } }
客户端主方法:
public class ProxyMain { public static void main(String[] args) { ProxyHandler proxyHandler = new ProxyHandler(); // qmq SubjectProvider qmqSubjectProvider = (SubjectProvider) proxyHandler.bind(new QmqSubjectProvider()); System.out.println(qmqSubjectProvider.getSubject("1")); // qconfig SubjectProvider qconfigSubjectProvider = (SubjectProvider) proxyHandler.bind(new QconfigSubjectProvider()); System.out.println(qconfigSubjectProvider.getSubject("1")); } }
运行结果:
----com.balfish.hotel.train.proxy.QmqSubjectProvider
----interface com.balfish.hotel.train.proxy.SubjectProvider
before method...
1 qmqSubject
----com.balfish.hotel.train.proxy.QconfigSubjectProvider
----interface com.balfish.hotel.train.proxy.SubjectProvider
before method...
1 qconfigSubject
public final class $Proxy0 extends Proxy implements SubjectProvider { 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("***.SubjectProvider").getMethod("getSubject", 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()); } } //static 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 getSubject() { 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); } } }
四 适用场景
以上是关于java的动态代理的主要内容,如果未能解决你的问题,请参考以下文章