diff --git a/CHANGELOG.md b/CHANGELOG.md
index faec6d294..3d19d7b27 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,8 @@
* 【core 】 修改StrUtil.equals逻辑,改为contentEquals
* 【core 】 增加URLUtil.UrlDecoder
* 【core 】 增加XmlUtil.setNamespaceAware,getByPath支持UniversalNamespaceCache
+* 【core 】 增加XmlUtil.setNamespaceAware,getByPath支持UniversalNamespaceCache
+* 【aop 】 增加Spring-cglib支持,改为SPI实现
### Bug修复
* 【json 】 修复解析JSON字符串时配置无法传递问题
diff --git a/hutool-aop/pom.xml b/hutool-aop/pom.xml
index 73ba81733..e668a5e55 100644
--- a/hutool-aop/pom.xml
+++ b/hutool-aop/pom.xml
@@ -19,6 +19,7 @@
3.3.0
+ 5.2.5.RELEASE
@@ -34,5 +35,12 @@
compile
true
+
+ org.springframework
+ spring-core
+ ${spring.version}
+ compile
+ true
+
diff --git a/hutool-aop/src/main/java/cn/hutool/aop/interceptor/CglibInterceptor.java b/hutool-aop/src/main/java/cn/hutool/aop/interceptor/CglibInterceptor.java
index a157dd9b6..a4b7ddf02 100644
--- a/hutool-aop/src/main/java/cn/hutool/aop/interceptor/CglibInterceptor.java
+++ b/hutool-aop/src/main/java/cn/hutool/aop/interceptor/CglibInterceptor.java
@@ -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) {
// 异常回调(只捕获业务代码导致的异常,而非反射导致的异常)
diff --git a/hutool-aop/src/main/java/cn/hutool/aop/interceptor/SpringCglibInterceptor.java b/hutool-aop/src/main/java/cn/hutool/aop/interceptor/SpringCglibInterceptor.java
new file mode 100644
index 000000000..8f3afa390
--- /dev/null
+++ b/hutool-aop/src/main/java/cn/hutool/aop/interceptor/SpringCglibInterceptor.java
@@ -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;
+ }
+}
diff --git a/hutool-aop/src/main/java/cn/hutool/aop/proxy/ProxyFactory.java b/hutool-aop/src/main/java/cn/hutool/aop/proxy/ProxyFactory.java
index 24ac30871..8186ea668 100644
--- a/hutool-aop/src/main/java/cn/hutool/aop/proxy/ProxyFactory.java
+++ b/hutool-aop/src/main/java/cn/hutool/aop/proxy/ProxyFactory.java
@@ -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;
/**
* 代理工厂
* 根据用户引入代理库的不同,产生不同的代理对象
- *
- * @author looly
*
+ * @author looly
*/
-public abstract class ProxyFactory implements Serializable{
+public abstract class ProxyFactory implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 创建代理
*
- * @param 代理对象类型
+ * @param 代理对象类型
+ * @param target 被代理对象
+ * @param aspectClass 切面实现类,自动实例化
+ * @return 代理对象
+ * @since 5.3.1
+ */
+ public T proxy(T target, Class extends Aspect> aspectClass) {
+ return proxy(target, ReflectUtil.newInstanceIfPossible(aspectClass));
+ }
+
+ /**
+ * 创建代理
+ *
+ * @param 代理对象类型
* @param target 被代理对象
* @param aspect 切面实现
* @return 代理对象
*/
public abstract T proxy(T target, Aspect aspect);
-
+
/**
* 根据用户引入Cglib与否自动创建代理对象
- *
- * @param 切面对象类型
- * @param target 目标对象
+ *
+ * @param 切面对象类型
+ * @param target 目标对象
* @param aspectClass 切面对象类
* @return 代理对象
*/
- public static T createProxy(T target, Class extends Aspect> aspectClass){
+ public static T createProxy(T target, Class extends Aspect> aspectClass) {
return createProxy(target, ReflectUtil.newInstance(aspectClass));
}
/**
* 根据用户引入Cglib与否自动创建代理对象
- *
- * @param 切面对象类型
+ *
+ * @param 切面对象类型
* @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);
}
}
diff --git a/hutool-aop/src/main/java/cn/hutool/aop/proxy/SpringCglibProxyFactory.java b/hutool-aop/src/main/java/cn/hutool/aop/proxy/SpringCglibProxyFactory.java
new file mode 100644
index 000000000..46db19996
--- /dev/null
+++ b/hutool-aop/src/main/java/cn/hutool/aop/proxy/SpringCglibProxyFactory.java
@@ -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 proxy(T target, Aspect aspect) {
+ final Enhancer enhancer = new Enhancer();
+ enhancer.setSuperclass(target.getClass());
+ enhancer.setCallback(new SpringCglibInterceptor(target, aspect));
+ return (T) enhancer.create();
+ }
+
+}
diff --git a/hutool-aop/src/main/resources/META-INF/services/cn.hutool.aop.proxy.ProxyFactory b/hutool-aop/src/main/resources/META-INF/services/cn.hutool.aop.proxy.ProxyFactory
new file mode 100644
index 000000000..2bad43826
--- /dev/null
+++ b/hutool-aop/src/main/resources/META-INF/services/cn.hutool.aop.proxy.ProxyFactory
@@ -0,0 +1,3 @@
+cn.hutool.aop.proxy.CglibProxyFactory
+cn.hutool.aop.proxy.SpringCglibProxyFactory
+cn.hutool.aop.proxy.JdkProxyFactory
\ No newline at end of file
diff --git a/hutool-aop/src/test/java/cn/hutool/aop/test/AopTest.java b/hutool-aop/src/test/java/cn/hutool/aop/test/AopTest.java
index eb036d1d4..55da3d3e7 100644
--- a/hutool-aop/src/test/java/cn/hutool/aop/test/AopTest.java
+++ b/hutool-aop/src/test/java/cn/hutool/aop/test/AopTest.java
@@ -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);