1、什么是动态代理
说到动态代理,首先要清楚什么是静态代理。在程序运行之前,已经由程序员或工具自动生成源代码,然后再进行编译,类的class文件就已经
存在了。而代理存在的意义就是在程序运行之前并没有具体的源代码出现,也没有类的class文件,在程序运行时通过反射机制动态创建类。那今
天具体介绍两个动态代理的方式。
2、jdk的动态代理
在jdk中和动态代理的类相关的有两个:
(1)InvocationHandler
Object invoke(Object proxy,Method method,Object[] args)
介绍下各参数的作用:
Object:生成的代理类。
Method:代理类中的方法。
Object:方法的参数。
(2)Proxy
Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h)
介绍下各参数的作用:
ClassLoader:类加载器(这是一块很重要的知识,大家可以下去做功课哦)。
Interface:被代理类的接口。
h:invocationHandler类中的invoke方法。
下面具体介绍个列子:
client类:
public static void main(String[] args) { Dog tatget = new GunDog(); Dog dog = (Dog) MyProxyFactory.getProxy(tatget); dog.info(); dog.run(); }
代理类的具体实现:
package com.company; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.Collection; import java.util.Collections; /** * Created by Tong on 2016/8/14. */ public class MyInvokationHandler implements InvocationHandler { private Object target; public void setTarget(Object target){ this.target=target; } public Object invoke(Object proxy,Method method,Object[] args) throws Exception { DogUtil du=new DogUtil(); du.method1(); Object result=method.invoke(target,args); du.method2(); return result; } }
生成代理类:
package com.company; import java.lang.reflect.Proxy; /** * Created by Tong on 2016/8/14. */ public class MyProxyFactory { public static Object getProxy(Object target){ MyInvokationHandler handler=new MyInvokationHandler(); handler.setTarget(target); Object ProxyObje; ProxyObje= Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),handler); return ProxyObje; } }
Dog类:
package com.company; /** * Created by Tong on 2016/8/14. */ public interface Dog { void info(); void run(); }
DogUtil类:
<pre name="code" class="java">package com.company; /** * Created by Tong on 2016/8/14. */ public class DogUtil { public void method1(){ System.out.print("模拟第一个通用方法"); } public void method2(){ System.out.print("模拟第二个通用方法"); } }
GunDog:
<pre name="code" class="java">package com.company; /** * Created by Tong on 2016/8/14. */ public class GunDog implements Dog { public void info(){ System.out.print("我是一只猎狗"); } public void run(){ System.out.print("我奔跑迅速"); } }
运行结果:
这个列子是在原本猎狗奔跑的基础上,加了一个场景,有一天,猎狗奔跑,下雨了,看到输出的结果,调用了两次代理类,因为在最开始的Dog类
中有两个方法。
下面比较着jdk的动态代理说下cglib
1、cglib动态代理用到的是继承,而jdk的动态代理用到的接口,而且被代理的类必须有接口。
2、cglib用到的是MethodInterceptor这个接口
- public Object intercept(Object object, Method method, Object[] args,
- MethodProxy methodProxy)
3、在创建类的时候,cglib用了enhancer
- public Object getDaoBean(Class cls) {
- enhancer.setSuperclass(cls);
- enhancer.setCallback(this);
- return enhancer.create();
- }
以上就是动态代理实现的基本原理。