zoukankan      html  css  js  c++  java
  • 动态代理jdk和cglib的用法

    一:JDK动态代理

    JDK动态代理所用到的代理类在程序调用到代理类对象时才由JVM真正创建,JVM根据传进来的 业务实现类对象 以及 方法名 ,动态地创建了一个代理类的class文件并被字节码引擎执行,然后通过该代理类对象进行方法调用。

    案例

    1、定义业务接口以及实现类

    package com.yjc.jdkproxy;
    
    public interface DoSomeService {
        void doSome();
    }
    -------------------------------------------
    
    package com.yjc.jdkproxy;
    
    public class DoSomeServiceImpl implements DoSomeService {
        @Override
        public void doSome() {
            System.out.println("doSome++++++++++++++++++==");
        }
    }

    2.调用管理接口InvocationHandler 创建动态代理类

    package com.yjc.jdkproxy;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    
    public class DoSomeHandler implements InvocationHandler {
      //这其实业务实现类对象,用来调用具体的业务方法
        private  Object target;
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("before----------------------------");
          //调用真正的业务方法 Object invoke = method.invoke(target, args); System.out.println("after---------------------------"); return invoke; } public DoSomeHandler(Object target) { this.target = target;//接收业务实现类对象参数 } public DoSomeHandler() { } }

    测试方法

    package com.yjc.jdkproxy;
    
    import sun.misc.ProxyGenerator;
    
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.lang.reflect.Proxy;
    
    public class JdkProxyTest {
        public static void main(String[] args) throws IOException {
            DoSomeService doSomeService=new DoSomeServiceImpl();
         //通过反射机制,创建一个代理类对象实例并返回。用户进行方法调用时使用
            //创建代理对象时,需要传递该业务类的类加载器(用来获取业务实现类的元数据,在包装方法是调用真正的业务方法)、接口、handler实现类
    DoSomeService o = (DoSomeService)Proxy.newProxyInstance(doSomeService.getClass().getClassLoader(), new Class[]{DoSomeService.class}, new DoSomeHandler(doSomeService));   //调用目标函数
         o.doSome();
          //将内存中代理的类生成到本地 byte[] $proxy0s = ProxyGenerator.generateProxyClass("$proxy0", new Class[]{DoSomeService.class}); FileOutputStream fos=new FileOutputStream("F:/$proxy0.class"); fos.write($proxy0s); fos.flush(); fos.close(); } }

    二:CGLIB动态代理

         cglib是针对类来实现代理的,原理是对指定的业务类生成一个子类,并覆盖其中业务方法实现代理。因为采用的是继承,所以不能对final修饰的类进行代理。

     cglib和jdk动态代理的区别就是,cglib无需业务接口也可以实现动态代理,而jdk是在业务接口的基础上进行实现的,没有接口不行。cglib也需要项目对cglib的支持,需要引入依赖

    业务类

     
    package com.yjc.cglibproxy;
    
    public class DoSomeServiceImpl {
    
        public void doSome() {
            System.out.println("doSome++++++++++++++++++==");
        }
    }
     

    代理类

    package com.yjc.cglibproxy;
    
    import net.sf.cglib.proxy.MethodInterceptor;
    import net.sf.cglib.proxy.MethodProxy;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    
    public class DoSomeHandler implements MethodInterceptor {
        //目标对象
        private  Object target;
    
    
        public DoSomeHandler(Object target) {
            this.target = target;
        }
    
        public DoSomeHandler() {
        }

    /**

    * 方法描述 当对基于代理的方法回调时,在调用原方法之前会调用该方法
    * 拦截对目标方法的调用
    *
    * @param obj 代理对象
    * @param method 拦截的方法
    * @param args 拦截的方法的参数
    * @param proxy 代理
    * @return
    * @throws Throwable
    */

        @Override
        public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
            System.out.println("before==========================");
            Object invoke = method.invoke(target, objects);
            System.out.println("after============================");
            return invoke;
        }
    }

    测试类

    package com.yjc.cglibproxy;
    
    import net.sf.cglib.proxy.Enhancer;
    
    public class CglibProxyTest {
        public static void main(String[] args) {
            Enhancer enhancer=new Enhancer(); 
    // 设置目标对象的Class
    enhancer.setSuperclass(DoSomeServiceImpl.class); 
      // 设置回调操作,相当于InvocationHandler
    enhancer.setCallback(new DoSomeHandler(new DoSomeServiceImpl()));
    DoSomeServiceImpl o =(DoSomeServiceImpl) enhancer.create();
    o.doSome();
    } }
  • 相关阅读:
    eclipse快捷键
    Struts2框架(8)---Struts2的输入校验
    Struts2框架(5)---result结果集
    Spring框架(6)---AspectJ实现AOP
    Spring框架(4)---AOP讲解铺垫
    Spring框架(3)---IOC装配Bean(注解方式)
    Spring框架(2)---IOC装配Bean(xml配置方式)
    Spring框架(1)---Spring入门
    Mybatis框架(5)---动态sql
    Mybatis框架(4)---输入输出映射
  • 原文地址:https://www.cnblogs.com/rzbwyj/p/11753526.html
Copyright © 2011-2022 走看看