动态代理之基于Jdk的动态代理

67 阅读4分钟


携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第7天,点击查看活动详情

哈喽,大家好!我是Why,一名在读学生,目前刚刚开始进入自己的编程学习生涯。虽然学习起步较晚,但我坚信做了才有0或1的可能。学了一段时间以后也是选择在掘金上分享自己的日常笔记,也希望能够在众多道友的大家庭中打成一片。 本文主要讲解动态代理之基于Jdk的动态代理,如果大家读后觉得有用的话,还请大家多多支持博主:欢迎 ❤️点赞👍、收藏⭐、留言💬 ✨✨✨个人主页:JinHuan

动态代理

基于Jdk的动态代理

 /*
 newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 
 ClassLoader :类加载器,因为动态代理类,借助别人的类加载器。一般使用被代理对象的类加载器。
 Class<?>[] interfaces:接口类对象的集合,针对接口的代理,针对哪个接口做代理,一般使用的就是被代理对象的接口。
 InvocationHandler:句柄,回调函数,编写代理的规则代码
 public Object invoke(Object arg0, Method arg1, Object[] arg2)
 Object arg0:代理对象
 Method arg1:被代理的方法
 Object[] arg2:被代理方法被执行的时候的参数的数组  
 */
基础版
 package com.jinhuan.dynamicProxy;
 ​
 import com.jinhuan.service.BookService;
 import com.jinhuan.service.IService;
 ​
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
 ​
 /**
  * @Author jinhuan
  * @Date 2022/7/4 8:12
  * Description:基于JDK的动态代理
  */
 public class JdkProxy {
     public static void main(String[] args) {
         //被代理对象
         BookService bookService = new BookService();
         //返回代理对象
         /**
          * 第一个参数:被代理对象的类加载器
          * 第二个参数:被代理对象的接口对象集合
          * 第三个参数:回调函数,在这里编写代理的规则
          * */
         IService service = (IService) Proxy.newProxyInstance(
                 bookService.getClass().getClassLoader(),
                 bookService.getClass().getInterfaces(),
                 new InvocationHandler() {
                     /**
                      * 第一个参数:被代理对象
                      * 第二个参数:被代理对象的方法
                      * 第三个参数:被代理对象的参数
                      * */
                     @Override
                     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                         try {
                             System.out.println("开始事务!");
                             /**
                              * method.invoke:加强方法
                              * 第一个参数:被代理对象
                              * 第二个参数:需要加强的方法参数
                              * */
                             Object invoke = method.invoke(bookService, args);//这个相当于核心方法
                             System.out.println("结束事务");
                             return invoke;
                         } catch(Exception e) {
                             System.out.println("事务回滚");
                             e.printStackTrace();
                             throw e;
                         }finally {
                             System.out.println("finally-----");
                         }
                     }
                 }
         );
 ​
         //使用代理对象【干活】
         service.add();
     }
 ​
 }

image-20220704084441249

优化版

第一次优化

优化ProxyHandler

第二次优化

优化出代理工厂

JdkProxy

 package com.jinhuan.dynamicProxy;
 ​
 import com.jinhuan.service.BookService;
 import com.jinhuan.service.IService;
 ​
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
 ​
 /**
  * @Author jinhuan
  * @Date 2022/7/4 8:12
  * Description:基于JDK的动态代理
  */
 public class JdkProxy {
     public static void main(String[] args) {
         //被代理对象
         BookService bookService = new BookService();
         //返回代理对象
         /**
          * 第一个参数:被代理对象的类加载器
          * 第二个参数:被代理对象的接口对象集合
          * 第三个参数:回调函数,在这里编写代理的规则
          * */
         IService service = (IService) Proxy.newProxyInstance(
                 bookService.getClass().getClassLoader(),
                 bookService.getClass().getInterfaces(),
                 new InvocationHandler() {
                     /**
                      * 第一个参数:被代理对象
                      * 第二个参数:被代理对象的方法
                      * 第三个参数:被代理对象的参数
                      * */
                     @Override
                     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                         try {
                             System.out.println("开始事务!");
                             /**
                              * method.invoke:加强方法
                              * 第一个参数:被代理对象
                              * 第二个参数:需要加强的方法参数
                              * */
                             Object invoke = method.invoke(bookService, args);//这个相当于核心方法
                             System.out.println("结束事务");
                             return invoke;
                         } catch(Exception e) {
                             System.out.println("事务回滚");
                             e.printStackTrace();
                             throw e;
                         }finally {
                             System.out.println("finally-----");
                         }
                     }
                 }
         );
 ​
         //使用代理对象【干活】
         service.add();
     }
 ​
 }

MyProxyHandler

 package com.jinhuan.dynamicProxy;
 ​
 import com.jinhuan.aop.Aop;
 import com.jinhuan.service.IService;
 ​
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
 ​
 /**
  * @Author jinhuan
  * @Date 2022/7/4 8:45
  * Description:
  */
 public class MyProxyHandler implements InvocationHandler {
     private IService service;
     private Aop aop;
 ​
 ​
     public MyProxyHandler(IService service, Aop aop) {
         this.service = service;
         this.aop = aop;
     }
 ​
     @Override
     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
         try {
             aop.before();
             Object invoke = method.invoke(service, args);//这个相当于核心方法
             aop.after();
             return invoke;
         } catch(Exception e) {
             aop.exception();
             e.printStackTrace();
             throw e;
         }finally {
             aop.myFinally();
         }
     }
 }

ProxyFactory

 package com.jinhuan.dynamicProxy;
 ​
 import com.jinhuan.aop.Aop;
 import com.jinhuan.aop.LogAop;
 import com.jinhuan.aop.TranAop;
 import com.jinhuan.service.BookService;
 import com.jinhuan.service.IService;
 ​
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
 ​
 /**
  * @Author jinhuan
  * @Date 2022/7/4 8:56
  * Description:专门产生代理类的工厂
  */
 public class ProxyFactory {
     private IService service;
     private Aop aop;
 ​
     public ProxyFactory(IService service, Aop aop) {
         this.service = service;
         this.aop = aop;
     }
 ​
     /**
      * @param :
      * @return java.lang.Object
      * decription: 获取动态代理的实例
      */
     public Object getProxyInstance(){
         return Proxy.newProxyInstance(
                 service.getClass().getClassLoader(),
                 service.getClass().getInterfaces(),
                 new InvocationHandler() {
                     @Override
                     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                         try {
                             aop.before();
                             Object invoke = method.invoke(service, args);//这个相当于核心方法
                             aop.after();
                             return invoke;
                         } catch(Exception e) {
                             aop.exception();
                             e.printStackTrace();
                             throw e;
                         }finally {
                             aop.myFinally();
                         }
                     }
                 }
         );
     }
 }

TestJdkProxy

 package com.jinhuan.test;
 ​
 import com.jinhuan.aop.Aop;
 import com.jinhuan.aop.LogAop;
 import com.jinhuan.aop.TranAop;
 import com.jinhuan.dynamicProxy.MyProxyHandler;
 import com.jinhuan.dynamicProxy.ProxyFactory;
 import com.jinhuan.service.BookService;
 import com.jinhuan.service.IService;
 import org.junit.Test;
 ​
 import java.lang.reflect.Proxy;
 ​
 /**
  * @Author jinhuan
  * @Date 2022/7/4 8:36
  * Description:
  */
 public class TestJdkProxy {
     @Test
     /**
      * 第一次优化Jdk动态代理
      * */
     public void test() {
         //被代理对象
         BookService bookService = new BookService();
         Aop tranAop = new TranAop();
         Aop logAop = new LogAop();
 ​
         //返回代理对象
         /**
          * 第一个参数:被代理对象的类加载器
          * 第二个参数:被代理对象的接口对象集合
          * 第三个参数:回调函数,在这里编写代理的规则
          * */
         IService service = (IService) Proxy.newProxyInstance(
                 bookService.getClass().getClassLoader(),
                 bookService.getClass().getInterfaces(),
                 new MyProxyHandler(bookService,tranAop)
         );
 ​
         //使用代理对象【干活】
         service.add();
     }
 ​
     /**
      * 第二次优化
      * */
     @Test
     public void test01(){
         //被代理对象
         BookService bookService = new BookService();
         Aop tranAop = new TranAop();
         Aop logAop = new LogAop();
 ​
         //获取被代理对象       一级代理
         IService service1 = (IService) new ProxyFactory(bookService, tranAop).getProxyInstance();
         //二级代理
         IService service2 = (IService) new ProxyFactory(service1, logAop).getProxyInstance();
         service1.add();
         service2.add();
     }
 }

image-20220704090829432