一、前言
经测试,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;
}
}
四、结果


声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

评论(0)