动态代理与子类代理

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态代理与子类代理相关的知识,希望对你有一定的参考价值。

1.动态代理

java.lang.reflect.Proxy 对象
帮我们生成一个代理对象来完成这个记录日志的工作

技术分享

 
动态代理:被代理的对象一定要实现接口
loader: 类加载器,跟被代理对象(UserDao)一致即可
interfaces 被代理对象的接口列表
h这个参数: 传入的是这个接口的实现类

 技术分享

动态生成的子类

技术分享

 1 //使用动态代理工具生成代理对象
 2 public class DynamicProxyUtil {
 3    /**
 4     * 获取动态代理对象
 5     * @param obj   目标对象
 6     * @return      代理对象
 7     */
 8    public static  Object getProxyObj(final Object obj){
 9       return Proxy.newProxyInstance(
10             //获取类加载器
11             obj.getClass().getClassLoader(),
12             //获取接口列表
13             obj.getClass().getInterfaces(),
14             //增强的功能在这里
15             new InvocationHandler() {
16                 /**
17                  * proxy :代理对象
18                  * method:方法
19                  * args:参数列表
20                  */
21                 @Override
22                 public Object invoke(Object proxy, Method method, Object[] args)
23                       throws Throwable {
24                    //记录日志
25                    System.out.println("记录日志了.......");   
26                    //回调目标对象的方法
27                    /* obj:目标对象
28                     * args: 参数列表
29                     */
30                    method.invoke(obj, args);      
31                    return null;

技术分享

 

 

 2.子类代理

子类也是一种增强的方式
通过第三方的工具来实现子类代理: Cglib
Enhancer类来帮我们生成子类的代理
1)导jar包,我们springioc包中已经集成cglig的包

 

 1 //子类代理
 2 public class SubProxyUtil {
 3    /**
 4     * 通过这个方法生成被代理对象的子类
 5     * @param obj
 6     * @return
 7     */
 8    public static Object getSubProxyObj(final Object obj){
 9       //通过cglig的工具类生成子类的代理对象
10       Enhancer en = new Enhancer();
11       //传入父类
12       en.setSuperclass(obj.getClass());
13       //做增强,回调
14       en.setCallback(new MethodInterceptor() {     
15          //这个方法就是做的增强
16          /**
17           * arg0 :代理对象
18           * Method:被代理对象的方法
19           * arg2:参数列表
20           * MethodProxy:代理对象的方法
21           */
22          @Override
23          public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
24             
25             if(arg1.getName().equals("save")){
26                 //增强
27                 System.out.println("记录日志了:"+arg1.getName());
28             }
29             //回调
30             /*
31              * obj:传入被代理的对象
32              * arg2:方法中使用的参数
33              */
34             arg1.invoke(obj, arg2);
35             return null;
36          }
37       });
38       //返回被代理对象的子类
39       return en.create();
40   /* 子类代理:帮我们完成记录日志的工作
41        */
42       //被代理的对象
43       UserDaoImpl2 userdao = new UserDaoImpl2();
44       //返回的子类
45       UserDaoImpl2 proxy = (UserDaoImpl2)SubProxyUtil.getSubProxyObj(userdao);
46       proxy.save();
47       proxy.update();

 

 技术分享

 

以上是关于动态代理与子类代理的主要内容,如果未能解决你的问题,请参考以下文章

反射机制-动态代理

CGlib和JDK动态代理

DK动态代理与CGLib动态代理的区别

java动态代理实现--基于子类的动态代理

CGLib动态代理原理及实现

CGLib动态代理原理及实现