Java基础之动态代理Cglib详解

一、前言

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

二、服务

package proxy.cglib;

/**
 * @Description: <br/>
 * 订单服务
 * <p>
 * <br/>
 * @Author: Qz1997
 * @create 2021/5/1 10:51
 */
public class OrderServiceImpl {
    /**
     * 下单
     *
     * @param orderNo 订单号
     * @return 结果
     */
    public String preOrder(String orderNo) {
        System.out.println("OrderServiceImpl.preOrder" + orderNo);
        return "下单成功";
    }

    /**
     * 下单
     *
     * @return 结果
     */
    public String list() {
        return "list";
    }
}

三、代理工厂

package proxy.cglib;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Objects;

/**
 * @Description: <br/>
 * Cglib 通过继承的方式 实习代理
 * final类 和 final 方法 不能代理
 * <p>
 * <br/>
 * @Author: Qz1997
 * @create 2021/5/1 13:24
 */
public class CglibProxyFactory implements MethodInterceptor {

    /**
     * 创建一个代理对象
     *
     * @param clazz 类型
     * @return 代理对象
     */
    public Object creatProxyedObj(Class<?> clazz) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(this);
        return enhancer.create();
    }

    /**
     * 代理方法
     *
     * @param proxyObject 代理对象
     * @param method      方法
     * @param args        方法参数
     * @param methodProxy 代理方法
     * @return
     * @throws Throwable
     */
    @Override
    public Object intercept(Object proxyObject, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        // 判断方法参数 如果是null || 参数格式 <= 0
        if (Objects.isNull(args) || args.length <= 0) {
            return methodProxy.invokeSuper(proxyObject, args);
        }
        /// // 判断这个方法上是否包含某个注解
        // if (method.isAnnotationPresent(Async.class)) {
        //     // ....进行一顿增强
        //     // return method.invoke(proxy, arg);
        // }
        Parameter[] parameters = method.getParameters();
        Parameter parameter = parameters[0];
        Class<?> type = parameter.getType();
        // 类型为String
        if (type == String.class) {
            String orderNo = (String) args[0];
            if (Objects.nonNull(orderNo) && orderNo.length() < 10) {
                throw new RuntimeException("订单号错误");
            }
        }
        String result = (String) methodProxy.invokeSuper(proxyObject, args);
        if (Objects.equals(result, "下单成功")) {
            System.out.println("发动订单短信");
        }
        return result;
    }

}

四、结果


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

(0)

相关推荐

  • JAVA中的静态代理、动态代理以及CGLIB动态代理总结

    代理模式是java中最常用的设计模式之一,尤其是在spring框架中广泛应用.对于java的代理模式,一般可分为:静态代理.动态代理.以及CGLIB实现动态代理. 对于上述三种代理模式,分别进行说明. 1.静态代理 静态代理其实就是在程序运行之前,提前写好被代理方法的代理类,编译后运行.在程序运行之前,class已经存在. 下面我们实现一个静态代理demo: 静态代理 定义一个接口Target package com.test.proxy; public interface Target { p

  • Java使用JDK与Cglib动态代理技术统一管理日志记录

    Java中动态代理主要有JDK和CGLIB两种方式. 区别主要是jdk是代理接口,而cglib是代理类. 优点:这种方式已经解决我们前面所有日记需要的问题.非常的灵活.而且可以方便的在后期进行维护和升级. 缺点:当然使用jdk动态代理,必需要有接口.如果没有接口.就无法使用jdk动态代理技术. 计算接口 Calculate.java public interface Calculate { /** * 加法运算 * @param num1 参数 1 * @param num2 参数 2 * @r

  • java动态代理(jdk与cglib)详细解析

    JAVA的动态代理 代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务. 按照代理的创建时期,代理类可以分为两种. 静态代理:由程序员创建或特定工具自动生成源代码,再对其编译.在程序运行前,代理类的.class文件就已经

  • 详解Java Cglib动态代理

    今天来介绍另一种更为强大的代理--Cglib动态代理. 什么是Cglib动态代理? 我们先回顾一下上一篇的jdk动态代理,jdk动态代理是通过接口来在运行时动态创建委托类的代理对象,但是跟静态代理一样有一个缺点,就是必须和委托类实现相同的接口,当接口数量增加时,便需要增加代理类的数量才能满足需求,而且如果委托类是别人写的,而且没有实现任何接口,那么jdk动态代理就有些力不从心了. 这时候Cglib动态代理就脱颖而出了,Cglib并不依赖接口,可以直接生成委托类的代理对象,而且可以代理委托类的任意

  • java 中动态代理(JDK,cglib)实例代码

    java 动态代理实例详解 1.jdk动态代理 /** * */ package com.sinosoft; /** *接口:编写一个委托类的接口,即静态代理的(Apple接口) * */ public interface Apple { public void phoneCall(); } /** * */ package com.sinosoft; /** * 实现一个真正的委托类,即静态代理的(AppleImpl类) * */ public class AppleImpl implemen

  • 深入理解java动态代理的两种实现方式(JDK/Cglib)

    什么是代理模式? 代理模式:在调用处不直接调用目标类进行操作,而是调用代理类,然后通过代理类来调用目标类进行操作.在代理类调用目标类的前后可以添加一些预处理和后处理操作来完成一些不属于目标类的功能. 为什么要使用代理模式? 通过代理模式可以实现对目标类调用的控制.在目标类调用前/后进行一些不属于目标类的操作,如:数据验证.预处理.后处理.异常处理等 什么是静态代理什么是动态代理? 静态代理:代理类只能实现对"特定接口的实现类"进行代理 动态代理:代理类可以实现对多种类的代理 jdk代理

  • Java CGLib动态代理机制(全面解析)

    一.首先说一下JDK中的动态代理: JDK中的动态代理是通过反射类Proxy以及InvocationHandler回调接口实现的 但是,JDK中所要进行动态代理的类必须要实现一个接口,也就是说只能对该类所实现接口中定义的方法进行代理,这在实际编程中具有一定的局限性,而且使用反射的效率也并不是很高. 二.使用CGLib实现: 使用CGLib实现动态代理,完全不受代理类必须实现接口的限制,而且CGLib底层采用ASM字节码生成框架,使用字节码技术生成代理类,比使用Java反射效率要高.唯一需要注意的

  • 浅谈Java代理(jdk静态代理、动态代理和cglib动态代理)

    一.代理是Java常用的设计模式,代理类通过调用被代理类的相关方法,并对相关方法进行增强.加入一些非业务性代码,比如事务.日志.报警发邮件等操作. 二.jdk静态代理 1.业务接口 /** * 业务接口 * @author pc * */ public interface UserService { // 增加一个用户 public void addUser(); // 编辑账户 public void editUser(); } 2.业务实现类 /** * 业务实现类 * @author pc

  • java动态代理和cglib动态代理示例分享

    java动态代理类可以分为两种. 静态代理:由程序员创建或特定工具自动生成源代码,再对其编译.在程序运行前,代理类的.class文件就已经存在了. 动态代理:在程序运行时,运用反射机制动态创建而成. 一.首先我们进行java动态代理的演示. 现在我们有一个简单的业务接口Saying,如下: 复制代码 代码如下: package testAOP;public interface Saying {public void sayHello(String name);    public void ta

  • Java 动态代理与CGLIB详细介绍

    静态代理模式 因为需要对一些函数进行二次处理,或是某些函数不让外界知道时,可以使用代理模式,通过访问第三方,间接访问原函数的方式,达到以上目的. interface Hosee{ String sayhi(); } class Hoseeimpl implements Hosee{ @Override public String sayhi() { return "Welcome oschina hosee's blog"; } } class HoseeProxy implement

随机推荐