• JDK动态代理与CGLIB动态代理


    一、jdk动态代理  代理目标是 接口实现类的形式

    代理的目标对象:

     1 public class PersonServiceImpl implements PersonService {
     2     private Person person;
     3     @Override
     4     public void savePerson() {
     5         System.out.println("保存用户");
     6     }
     7     public Person getPerson() {
     8         return person;
     9     }
    10     public void setPerson(Person person) {
    11         this.person = person;
    12     }
    13 }

    代理:

     1 /**
     2  * 创建动态代理类,需要实现InvocationHandler接口
     3  */
     4 public class JDKProxy implements InvocationHandler{
     5     //指定目标代理对象
     6     private Object     targetObj;
     7     public Object createObjectProxyInstance(Object targetObj){
     8         this.targetObj = targetObj;
     9         /**
    10          * 第一个参数:目标对象的类的加载器
    11          * 第二个参数:目标对象的接口
    12          * 第三个参数:设置回掉对象,当前代理对象的方法被调用时,会委派改参数去调用invoke
    13          */
    14         return Proxy.newProxyInstance(this.targetObj.getClass().getClassLoader(), this.targetObj.getClass().getInterfaces(), this);
    15     }
    16     /**
    17      * proxy:代理类
    18      * method:要调用的业务方法
    19      * args:调用业务方法的参数
    20      */
    21     @Override
    22     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    23         //通过反射获得getPerson方法
    24         Method getMeth = this.targetObj.getClass().getMethod("getPerson", null);
    25         Object person = getMeth.invoke(targetObj, null);
    26         Object obj = null;
    27         if(person != null){
    28             obj = method.invoke(targetObj, args);
    29         }else{
    30             System.out.println("你没有登陆");
    31         }
    32         return obj;
    33     }
    34 }

    测试:

    1 @Test
    2     public void test1(){
    3         PersonServiceImpl psi = new PersonServiceImpl();
    4         psi.setPerson(new Person());
    5         PersonService ps = (PersonService) new JDKProxy().createObjectProxyInstance(psi);
    6         System.out.println(ps.getClass());
    7         ps.savePerson();
    8     }

    二、CGLIB动态代理

    可以对普通类实现代理,但该类不能被final修饰,方法也不能被final修饰

    代理:

     1 public class CGLIBProxy implements MethodInterceptor{
     2     //指定代理目标对象
     3     private Object targetObj;
     4     public Object creatProxyInstance(Object targetObj){
     5         this.targetObj = targetObj;
     6         Enhancer en = new Enhancer();
     7         //设置代理类的父类
     8         en.setSuperclass(this.targetObj.getClass());
     9         //设置回掉对象
    10         en.setCallback(this);
    11         //创建代理类
    12         return en.create();
    13     }
    14     @Override
    15     public Object intercept(Object arg0, Method method, Object[] arg2, MethodProxy arg3) throws Throwable {
    16         //通过反射获得getPerson方法
    17         Method tarMeth = this.targetObj.getClass().getMethod("getPerson", null);
    18         Person person = (Person) tarMeth.invoke(this.targetObj, null);
    19         Object obj = null;
    20         if(person != null){
    21             obj = method.invoke(this.targetObj, arg2);
    22         }else{
    23             System.out.println("没有登陆");
    24         }
    25         return obj;
    26     }
    27 }

    测试:

    1 @Test
    2     public void test2(){
    3         PersonServiceImpl psi = new PersonServiceImpl();
    4         psi.setPerson(new Person());
    5         PersonServiceImpl ps =  (PersonServiceImpl) new CGLIBProxy().creatProxyInstance(psi);
    6         System.out.println(ps.getClass());
    7         ps.savePerson();
    8     }
  • 相关阅读:
    [转]Docker学习笔记之一,搭建一个JAVA Tomcat运行环境
    ubuntu wifi连接出现Network service discovery disabled的解决办法
    使用java实现对称加密解密(AES),非对称加密解密(RSA)
    [转] mysql分区性能初探
    CyclicBarrier和CountDownLatch的使用
    oom 和 jvm crash的问题
    使用单元素枚举实现单例
    【转】mysql 计划事件
    用Linkedhashmap的LRU特性及SoftReference软引用构建二级缓存
    动态生成正则表达式
  • 原文地址:https://www.cnblogs.com/cat-fish6/p/8689052.html
Copyright © 2020-2023  润新知