浅析Java中的动态代理

目录
  • 代理常见功能
  • 代理模式的组成
  • 代理模式分类
  • 动态代理实现的技术
  • JDK 代理的实现步骤
  • CGLIB 代理实现步骤

代理常见功能

日志代理

数据库访问的事务代理

代理模式的组成

  • 抽象主题:通过接口或抽象类定义核心业务方法。
  • 真实主题:实现了接口的实现类,是实施代理的具体对象。即代理最终代理的是具体的实现类类而不是接口。
  • 代理:具有与代理对象相同的方法,可以控制和扩展被代理对象的功能,也是使用代理对象的根据目的。

代理对象 = 增强代码 + 目标对象(原对象)

代理模式分类

静态代理:代理类与被代理类一一对应,缺点是代理类太多。

动态代理:代理类是运行时通过反射技术动态生成的。有点是一类相似功能的被代理类(即需要相同扩展功能的类)只需要一个动态代理类。

动态代理实现的技术

JDK 代理:面向接口的代理,无法直接代理类,被代理的类必须实现某业务接口。

CGLIB 代理:功能更强,性能更好,可以直接代理类而不用实现接口,是通过动态创建被代理的子类重写父类的被代理方法来实现统计附件功能的。不能代理final类或final方法。

JDK 代理的实现步骤

核心业务接口

public interface Buyer {
    /**
     * 卖房:核心业务方法
     * @return
     */
    String buy();
}

业务实现类

public class BuyerImpl implements Buyer{
    public String buy() {
        System.out.println("本人卖房,从不坑人...");
        return "一次搞定";
    }
}

动态代理类

public class BuyerInvocationHandler implements InvocationHandler {
    //被代理对象
    private Object target;

    /**
     * 设置被代理对象
     * @param target
     */
    public void setTarget(Object target) {
        this.target = target;
    }

    /**
     * 执行被代理对象的业务方法的代理方法
     * @param proxy
     * @param method
     * @param args
     * @return
     * @throws Throwable
     */
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("熬夜满大街收集电话号码.....");
        //调用核心业务方法
        Object result = method.invoke(target,args);

        System.out.println("不满意,再找我...");

        return result;
    }
}

代理工厂类

public class BuyerProxyFactory {
    /**
     * 工厂方法
     * @param target 需要被代理的对象
     * @param <T>
     * @return 返回动态生成的代理对象
     */
    public static <T> T create(Object target){
        // 创建动态代理对象
        BuyerInvocationHandler handler = new BuyerInvocationHandler();
        // 设置被代理对象
        handler.setTarget(target);
        // 动态创建执行业务方法的代理对象
        return  (T) Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                handler);
    }
}

测试类

public class example {
    public static void main(String[] args) {
        //定义被代理对象
        //定义被代理对象
        Buyer buyer = new BuyerImpl();
        buyer.buy();  // 直接调用业务方法,没有代理的功能
        // 使用代理工厂创建动态代理类对象
        Buyer proxyBuyer = BuyerProxyFactory.create(buyer);
        proxyBuyer.buy();
    }
}

CGLIB 代理实现步骤

导入 POM

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib-nodep</artifactId>
    <version>3.3.0</version>
</dependency>

定义业务方法

public class OrderService {
    public int insert(){
        System.out.println("添加订单....");
        return 0;
    }
}

定义代理工厂类,与提供事务控制功能的MethodInterceptor合二为一

public class TransactionProxyFactory {
    /**
     * 动态创建被代理类的代理对象
     * @param clazz 类型
     * @param <T>
     * @return 代理对象
     */
    public static <T> T create(Class<T> clazz){
        Enhancer enhancer = new Enhancer();
        // 采用接口内部类的方式实现代理功能
        enhancer.setCallback(new MethodInterceptor() {
            public Object intercept(Object target, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                System.out.println("开始事务。。。。");
                // 核心业务,调用父类的方法
                Object result = methodProxy.invokeSuper(target,objects);
                System.out.println("提交或回滚事务....");
                return result;
            }
        });
        // 设置代理类的父类
        enhancer.setSuperclass(clazz);
        // 返回创建的动态代理类对象
        return (T) enhancer.create();
    }
}

测试类

public class TransactionProxyFactoryTest {
    public static void main(String[] args) {
        // 使用代理创建业务逻辑类
        OrderService orderService =
                TransactionProxyFactory.create(OrderService.class);
        orderService.insert();

        CartService cartService = TransactionProxyFactory.create(CartService.class);
        cartService.insert();
    }
}

到此这篇关于浅析Java中的动态代理的文章就介绍到这了,更多相关Java动态代理内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 一文了解Java动态代理的原理及实现

    代理是指:某些场景下对象会找一个代理对象,来辅助自己完成一些工作,如明星的经纪人.买房的人找房产中介等. 代理主要是对对象的行为额外做一些辅助操作. 如何创建代理对象: Java中代理的代表类是:Java.lang.reflect.Proxy Proxy提供了一个静态方法,用于为对象产生一个代理对象返回 主类: public class Test { public static void main(String[] args) { //1.创建一个类,对象类必须实现接口 star s=new s

  • Java代理模式实例详解【静态代理与动态代理】

    本文实例讲述了Java代理模式.分享给大家供大家参考,具体如下: 即Proxy Pattern,23种java常用设计模式之一.代理模式的定义:对其他对象提供一种代理以控制对这个对象的访问. Java的代理模式是Java中比较常用的设计模式,分为2中代理:静态代理与动态代理(JDK动态代理和cglib动态代理) 优点: 职责清晰 真实角色只需关注业务逻辑的实现,非业务逻辑部分,后期通过代理类完成即可. 高扩展性 不管真实角色如何变化,由于接口是固定的,代理类无需做任何改动. 缺点: 很明显的一点

  • Java实现JDK动态代理的原理详解

    目录 概念 案例 静态代理 JDK动态代理模式 原理分析 真相大白 概念 代理:为控制A对象,而创建出新B对象,由B对象代替执行A对象所有操作,称之为代理.一个代理体系建立涉及到3个参与角色:真实对象(A),代理对象(B),客户端. 其中的代理对象(B)起到中介作用,连通真实对象(A)与客户端,如果进一步拓展,代理对象可以实现更加复杂逻辑,比如对真实对象进行访问控制. 案例 需求:员工业务层接口调用save需要admin权限,调用list不需要权限,没权限调用时抛出异常提示. 静态代理 /**

  • Java动态代理的示例详解

    目录 定义 分类 案例 需求 方案一:jdk动态代理 方案二:cglib动态代理 分析 总结 定义 动态代理指的是,代理类和目标类的关系在程序运行的时候确定的,客户通过代理类来调用目标对象的方法,是在程序运行时根据需要动态的创建目标类的代理对象. 分类 jdk动态代理 cglib动态代理 案例 需求 苹果公司通过苹果代理商来卖手机 方案一:jdk动态代理 定义抽象接口 /** * 售卖手机的接口(代理模式--抽象角色) * @author:liyajie * @createTime:2022/2

  • Java动态代理四种实现方式详解

    代理模式也是一种非常常见的设计模式.了解Spring框架的都知道,Spring AOP 使用的就是动态代理模式.今天就来系统的重温一遍代理模式. 在现实生活中代理是随处可见的,当事人因某些隐私不方便出面,或者当事人不具备某些相关的专业技能,而需要一个职业人员来完成一些专业的操作, 也可能由于当事人没有时间处理事务,而聘用代理人出面.而在软件设计中,使用代理模式的地方也很多,由于安全原因,屏蔽客户端直接访问真实对象, 或者为了提升系统性能,使用代理模式实现延迟加载,还有就是AOP,对委托类的功能进

  • 浅析Java中的动态代理

    目录 代理常见功能 代理模式的组成 代理模式分类 动态代理实现的技术 JDK 代理的实现步骤 CGLIB 代理实现步骤 代理常见功能 日志代理 数据库访问的事务代理 代理模式的组成 抽象主题:通过接口或抽象类定义核心业务方法. 真实主题:实现了接口的实现类,是实施代理的具体对象.即代理最终代理的是具体的实现类类而不是接口. 代理:具有与代理对象相同的方法,可以控制和扩展被代理对象的功能,也是使用代理对象的根据目的. 代理对象 = 增强代码 + 目标对象(原对象) 代理模式分类 静态代理:代理类与

  • Java中JDK动态代理的超详细讲解

    目录 1. 什么是动态代理? 2.动态代理的实现方式有几种? 3. JDK动态代理 4. CGLB动态代理 5.动态代理的效率 6.为什么要使用动态代理呢? 7. JDK动态代理详细使用介绍 总结 1. 什么是动态代理? 动态代理是通过创建代理对象,在不改变原有代码的基础上,给程序增加新的功能,实现了程序的功能增强. 2.动态代理的实现方式有几种? JDK动态代理 CGLB动态代理 3. JDK动态代理 使用了JDK中的InvocationHandler接口,Method类和Proxy类.JDK

  • Java中反射动态代理接口的详解及实例

    Java语言中反射动态代理接口的解释与演示 Java在JDK1.3的时候引入了动态代理机制.可以运用在框架编程与平台编程时候捕获事件.审核数据.日志等功能实现,首先看一下设计模式的UML图解: 当你调用一个接口API时候,实际实现类继承该接口,调用时候经过proxy实现. 在Java中动态代理实现的两个关键接口类与class类分别如下: java.lang.reflect.Proxy java.lang.reflect.InvocationHandler 我们下面就通过InvocationHan

  • 深度剖析java中JDK动态代理机制

    摘要 相比于静态代理,动态代理避免了开发人员编写各个繁锁的静态代理类,只需简单地指定一组接口及目标类对象就能动态的获得代理对象. 代理模式 使用代理模式必须要让代理类和目标类实现相同的接口,客户端通过代理类来调用目标方法,代理类会将所有的方法调用分派到目标对象上反射执行,还可以在分派过程中添加"前置通知"和后置处理(如在调用目标方法前校验权限,在调用完目标方法后打印日志等)等功能. 使用动态代理的五大步骤 1.通过实现InvocationHandler接口来自定义自己的Invocati

  • 十分钟理解Java中的动态代理

    若代理类在程序运行前就已经存在,那么这种代理方式被成为 静态代理 ,这种情况下的代理类通常都是我们在Java代码中定义的. 通常情况下, 静态代理中的代理类和委托类会实现同一接口或是派生自相同的父类. 一.概述 1. 什么是代理 我们大家都知道微商代理,简单地说就是代替厂家卖商品,厂家"委托"代理为其销售商品.关于微商代理,首先我们从他们那里买东西时通常不知道背后的厂家究竟是谁,也就是说,"委托者"对我们来说是不可见的;其次,微商代理主要以朋友圈的人为目标客户,这就

  • 浅谈Java注解和动态代理

    本文主要介绍Java中与注解和动态代理有关的部分知识,接下来我们看看具体内容. Annotation(注解) 其实就是代码里的特殊标记, 它用于替代配置文件,也就是说,传统方式通过配置文件告诉类如何运行,有了注解技术后,开发人员可以通过注解告诉类如何运行. 1. 三个基本的Annotation: Override:限定重写父类方法, 该注解只能用于方法 Deprecated:用于表示某个程序元素(类, 方法等)已过时 SuppressWarnings:抑制编译器警告. 2.自定义Annotati

  • 浅析java中stringBuilder的用法

    String对象是不可改变的.每次使用 System.String类中的方法之一时,都要在内存中创建一个新的字符串对象,这就需要为该新对象分配新的空间.在需要对字符串执行重复修改的情况下,与创建新的 String对象相关的系统开销可能会非常昂贵.如果要修改字符串而不创建新的对象,则可以使用System.Text.StringBuilder类.例如,当在一个循环中将许多字符串连接在一起时,使用 StringBuilder类可以提升性能. 通过用一个重载的构造函数方法初始化变量,可以创建 Strin

  • Java设计模式之动态代理模式实例分析

    本文实例讲述了Java设计模式之动态代理模式.分享给大家供大家参考,具体如下: 前面介绍了静态代理模式,动态代理比静态代理模式更加强大.它能在程序运行时动态的生成代理对象.所谓动态代理类是在运行时生成的class,在生成它时,你必须提供一组interface给它,则动态代理类就宣称它实现了这些interface.当然,动态代理类就充当一个代理,你不要企图它会帮你干实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作. 动态代理的角色和静态代理的角色一样: ① 抽象角色:

  • Java设计模式之动态代理

    动态代理的意义在于生成一个占位(又称代理对象),来代理真实对象,从而控制真实对象的访问. 我们首先来谈谈什么是代理模式.假设客户带着需求去找公司,显然不会直接和软件工程师谈,而是和商务谈,此时客户会认为商务就代表公司,客户是通过商务去访问软件工程师的.我们就可以认为商务(代理对象)代理了软件工程师(真实对象),因此,代理的作用就是,在真实对象访问之前或者之后加入对应的逻辑,或者根据其他规则控制是否使用真实对象. 商务和软件工程师是代理和被代理的关系,客户是通过商务去访问软件工程师的.此时客户就是

  • Java基础之动态代理Cglib详解

    一.前言 经测试,jdk创建对象的速度远大于cglib,这是由于cglib创建对象时需要操作字节码.cglib执行速度略大于jdk,所以比较适合单例模式.另外由于CGLIB的大部分类是直接对Java字节码进行操作,这样生成的类会在Java的永久堆中.如果动态代理操作过多,容易造成永久堆满,触发OutOfMemory异常.spring默认使用jdk动态代理,如果类没有接口,则使用cglib. 二.服务 package proxy.cglib; /** * @Description: <br/>

随机推荐