一聚教程网:一个值得你收藏的教程网站

热门教程

Java基础之动态代理Cglib代码示例解析

时间:2022-06-29 00:54:00 编辑:袖梨 来源:一聚教程网

本篇文章小编给大家分享一下Java基础之动态代理Cglib代码示例解析,文章代码介绍的很详细,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看。

一、前言

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

二、服务

package proxy.cglib;

/**
 * @Description: 
* 订单服务 *

*
* @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: 
* Cglib 通过继承的方式 实习代理 * final类 和 final 方法 不能代理 *

*
* @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; } }

四、结果

热门栏目