add Spring cglib support

This commit is contained in:
Looly 2020-04-17 09:54:40 +08:00
parent 3526b39d4f
commit 94c824e03d
8 changed files with 134 additions and 21 deletions

View File

@ -11,6 +11,8 @@
* 【core 】 修改StrUtil.equals逻辑改为contentEquals
* 【core 】 增加URLUtil.UrlDecoder
* 【core 】 增加XmlUtil.setNamespaceAwaregetByPath支持UniversalNamespaceCache
* 【core 】 增加XmlUtil.setNamespaceAwaregetByPath支持UniversalNamespaceCache
* 【aop 】 增加Spring-cglib支持改为SPI实现
### Bug修复
* 【json 】 修复解析JSON字符串时配置无法传递问题

View File

@ -19,6 +19,7 @@
<properties>
<!-- versions -->
<cglib.version>3.3.0</cglib.version>
<spring.version>5.2.5.RELEASE</spring.version>
</properties>
<dependencies>
@ -34,5 +35,12 @@
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
</dependencies>
</project>

View File

@ -1,6 +1,7 @@
package cn.hutool.aop.interceptor;
import cn.hutool.aop.aspects.Aspect;
import cn.hutool.core.lang.Console;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
@ -42,6 +43,7 @@ public class CglibInterceptor implements MethodInterceptor, Serializable {
if (aspect.before(target, method, args)) {
try {
// result = proxy.invokeSuper(obj, args);
Console.log(target);
result = proxy.invoke(target, args);
} catch (InvocationTargetException e) {
// 异常回调只捕获业务代码导致的异常而非反射导致的异常

View File

@ -0,0 +1,65 @@
package cn.hutool.aop.interceptor;
import cn.hutool.aop.aspects.Aspect;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* Spring-cglib实现的动态代理切面
*
* @author looly
*/
public class SpringCglibInterceptor implements MethodInterceptor, Serializable {
private static final long serialVersionUID = 1L;
private final Object target;
private final Aspect aspect;
/**
* 构造
*
* @param target 被代理对象
* @param aspect 切面实现
*/
public SpringCglibInterceptor(Object target, Aspect aspect) {
this.target = target;
this.aspect = aspect;
}
/**
* 获得目标对象
*
* @return 目标对象
*/
public Object getTarget() {
return this.target;
}
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
final Object target = this.target;
Object result = null;
// 开始前回调
if (aspect.before(target, method, args)) {
try {
// result = proxy.invokeSuper(obj, args);
result = proxy.invoke(target, args);
} catch (InvocationTargetException e) {
// 异常回调只捕获业务代码导致的异常而非反射导致的异常
if (aspect.afterException(target, method, args, e.getTargetException())) {
throw e;
}
}
}
// 结束执行回调
if (aspect.after(target, method, args, result)) {
return result;
}
return null;
}
}

View File

@ -1,46 +1,59 @@
package cn.hutool.aop.proxy;
import java.io.Serializable;
import cn.hutool.aop.aspects.Aspect;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.ServiceLoaderUtil;
import java.io.Serializable;
/**
* 代理工厂<br>
* 根据用户引入代理库的不同产生不同的代理对象
*
* @author looly
*
* @author looly
*/
public abstract class ProxyFactory implements Serializable{
public abstract class ProxyFactory implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 创建代理
*
* @param <T> 代理对象类型
* @param <T> 代理对象类型
* @param target 被代理对象
* @param aspectClass 切面实现类自动实例化
* @return 代理对象
* @since 5.3.1
*/
public <T> T proxy(T target, Class<? extends Aspect> aspectClass) {
return proxy(target, ReflectUtil.newInstanceIfPossible(aspectClass));
}
/**
* 创建代理
*
* @param <T> 代理对象类型
* @param target 被代理对象
* @param aspect 切面实现
* @return 代理对象
*/
public abstract <T> T proxy(T target, Aspect aspect);
/**
* 根据用户引入Cglib与否自动创建代理对象
*
* @param <T> 切面对象类型
* @param target 目标对象
*
* @param <T> 切面对象类型
* @param target 目标对象
* @param aspectClass 切面对象类
* @return 代理对象
*/
public static <T> T createProxy(T target, Class<? extends Aspect> aspectClass){
public static <T> T createProxy(T target, Class<? extends Aspect> aspectClass) {
return createProxy(target, ReflectUtil.newInstance(aspectClass));
}
/**
* 根据用户引入Cglib与否自动创建代理对象
*
* @param <T> 切面对象类型
*
* @param <T> 切面对象类型
* @param target 被代理对象
* @param aspect 切面实现
* @return 代理对象
@ -51,15 +64,10 @@ public abstract class ProxyFactory implements Serializable{
/**
* 根据用户引入Cglib与否创建代理工厂
*
*
* @return 代理工厂
*/
public static ProxyFactory create() {
try {
return new CglibProxyFactory();
} catch (NoClassDefFoundError e) {
// ignore
}
return new JdkProxyFactory();
return ServiceLoaderUtil.loadFirstAvailable(ProxyFactory.class);
}
}

View File

@ -0,0 +1,25 @@
package cn.hutool.aop.proxy;
import cn.hutool.aop.aspects.Aspect;
import cn.hutool.aop.interceptor.SpringCglibInterceptor;
import org.springframework.cglib.proxy.Enhancer;
/**
* 基于Spring-cglib的切面代理工厂
*
* @author looly
*
*/
public class SpringCglibProxyFactory extends ProxyFactory{
private static final long serialVersionUID = 1L;
@Override
@SuppressWarnings("unchecked")
public <T> T proxy(T target, Aspect aspect) {
final Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target.getClass());
enhancer.setCallback(new SpringCglibInterceptor(target, aspect));
return (T) enhancer.create();
}
}

View File

@ -0,0 +1,3 @@
cn.hutool.aop.proxy.CglibProxyFactory
cn.hutool.aop.proxy.SpringCglibProxyFactory
cn.hutool.aop.proxy.JdkProxyFactory

View File

@ -23,7 +23,7 @@ public class AopTest {
}
@Test
public void aopByCglibTest() {
public void aopByAutoCglibTest() {
Dog dog = ProxyUtil.proxy(new Dog(), TimeIntervalAspect.class);
String result = dog.eat();
Assert.assertEquals("狗吃肉", result);