一、前言
经测试,jdk创建对象的速度远大于cglib,这是由于cglib创建对象时需要操作字节码。cglib执行速度略大于jdk,所以比较适合单例模式。另外由于CGLIB的大部分类是直接对Java字节码进行操作,这样生成的类会在Java的永久堆中。如果动态代理操作过多,容易造成永久堆满,触发OutOfMemory异常。spring默认使用jdk动态代理,如果类没有接口,则使用cglib。
二、服务
package proxy.cglib;
public class OrderServiceImpl {
public String preOrder(String orderNo) {
System.out.println("OrderServiceImpl.preOrder" + orderNo);
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;
public class CglibProxyFactory implements MethodInterceptor {
public Object creatProxyedObj(Class<?> clazz) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(clazz);
enhancer.setCallback(this);
return enhancer.create();
}
@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内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!