代理模式是为了提供额外或不一样的操做,而插入的用来替代”实际”对象的对象,这些操做涉及到与”实际”对象的通讯,所以代理一般充当中间人角色。java
java中经常使用的动态代理模式为jdk动态代理和cglib动态代理。框架
了解动态代理以前,须要先了解一下java中的反射,反射在框架中的应用很是普遍,它可以配置:类的全限定名,方法和参数。在运行时,动态的完成类的初始化,或者反射调用某些方法。ide
咱们能够经过Class.forName()方法加载类,并用getConstructor方法配置参数。例:测试
object = (goodsServiceImpl)=Class.forName("com.xjx.test.goodsServiceImpl").getConstructor(String.class).newInstance("计算机");
jdk动态代理由java.lang.reflect.*包提供,它必须借助一个接口才能实现代理。this
咱们举个例子来实现jdk动态代理并简要分析:spa
首先咱们定义一个接口:代理
public interface jdkProxy { public void test(String tString); }
以及它的实现类:code
public class jdkProxyImpl implements jdkProxy{ @Override public void test(String tString) { // TODO Auto-generated method stub
System.out.println("代理内方法"+tString); } }
接下来咱们要进行代理。代理过程分2步:对象
1.创建起代理对象和真实服务对象之间的关系,生产代理对象;blog
2.实现逻辑的代理;
在jdk动态代理中,要实现代理逻辑就必须实现InvocationHandler接口。它里面定义了一个invoke方法,每当咱们经过代理对象调用方法时,它都会被转发到这个invoke方法,咱们来
定义一个实现代理逻辑的类:
public class jdkProxyExample implements InvocationHandler{ //真实对象
private Object target = null; /** * 创建真实对象和代理对象的代理关系 * @param target真实对象 * @return 代理对象 */
public Object setTargetAndBind(Object target) { this.target = target; /** * 参数1:getClassLoader()提供类加载器;
参数2:getInterfaces()要挂载动态代理对象的接口,就是target的接口; */
return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(), this); } /** * 代理方法逻辑 * @param:代理对象 * method:当前调度方法 * args:当前方法参数 * return 代理结果返回 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("进入代理对象方法,在此执行代理对象以前的一些操做"); //执行目标对象中的某个方法
Object object = method.invoke(target, args); System.out.println("调用代理对象方法以后的操做"); return object; } }
setTargetAndBind()这个方法内的newProxyInstance()方法经过传入被代理内,再经过反射,生成一个代理类。
object obj = method.invoke(target,args),这个方法至关于调度真实对象的方法,只不过是经过反射区实现。它返回方法的执行结果。
而且在invoke方法里,能够在调用真实对象方法以前和以后作一些其余的操做,这也是AOP的实现原理。
这样,一个jdk动态代理就完成了,接下来能够写个测试类测试一下:
public class jdkProxyExampleTest { @Test public void testProxy() { jdkProxyExample jdkProxyExample = new jdkProxyExample(); //绑定关系,此时jdkProxy已是一个代理对象 jdkProxy jdkProxy = (jdkProxy)jdkProxyExample.setTargetAndBind(new jdkProxyImpl()); //执行代理对象方法 jdkProxy.test("动态代理jdk"); } }
打印结果以下:
1.咱们能够看到,在绑定关系的方法中,实现被代理类的反射,须要咱们提供接口,而后它经过接口实现代理类。没有它就找不到反射的方法。
2.因为java的单继承机制:首先jdk动态代理是经过newInstance动态的生成代理对象的,newInstance经过ProxyGenerator生成的字节码表明的类继承了Proxy类:
public final class $Proxy0 extends Proxy implements jdkProxy{ ... }
$Proxy0这个类经过反编译得到,它就是jdkProxy的实现类的动态的代理类。
因为java的单继承机制,被代理对象不能再被其余的类继承,那么咱们若是想创建代理类和被代理类之间的关系,只能经过实现同一个接口了。