From 1727e5c5666e8b80dcb08b90cc87dfa00424d033 Mon Sep 17 00:00:00 2001 From: Looly Date: Wed, 24 May 2023 23:59:07 +0800 Subject: [PATCH 1/2] fix bug --- .../engine/spring/SpringCglibProxyEngine.java | 44 +++++++++++-- .../hutool/extra/aop/IssueI74EX7Test.java | 63 ++++++++----------- 2 files changed, 66 insertions(+), 41 deletions(-) diff --git a/hutool-extra/src/main/java/org/dromara/hutool/extra/aop/engine/spring/SpringCglibProxyEngine.java b/hutool-extra/src/main/java/org/dromara/hutool/extra/aop/engine/spring/SpringCglibProxyEngine.java index cbfb7cc0c..bae44dc6b 100644 --- a/hutool-extra/src/main/java/org/dromara/hutool/extra/aop/engine/spring/SpringCglibProxyEngine.java +++ b/hutool-extra/src/main/java/org/dromara/hutool/extra/aop/engine/spring/SpringCglibProxyEngine.java @@ -12,25 +12,61 @@ package org.dromara.hutool.extra.aop.engine.spring; +import org.dromara.hutool.core.reflect.ClassUtil; +import org.dromara.hutool.core.reflect.ConstructorUtil; import org.dromara.hutool.extra.aop.Aspect; import org.dromara.hutool.extra.aop.engine.ProxyEngine; import org.springframework.cglib.proxy.Enhancer; +import java.lang.reflect.Constructor; + /** * 基于Spring-cglib的切面代理工厂 * * @author looly - * */ public class SpringCglibProxyEngine implements ProxyEngine { @Override - @SuppressWarnings("unchecked") public T proxy(final T target, final Aspect aspect) { + final Class targetClass = target.getClass(); + final Enhancer enhancer = new Enhancer(); - enhancer.setSuperclass(target.getClass()); + enhancer.setSuperclass(targetClass); enhancer.setCallback(new SpringCglibInterceptor(target, aspect)); - return (T) enhancer.create(); + + return create(enhancer, targetClass); } + /** + * 创建代理对象 + * + * @param 代理对象类型 + * @param enhancer {@link Enhancer} + * @param targetClass 目标类型 + * @return 代理对象 + */ + @SuppressWarnings("unchecked") + private static T create(final Enhancer enhancer, final Class targetClass) { + final Constructor[] constructors = ConstructorUtil.getConstructors(targetClass); + Class[] parameterTypes; + Object[] values; + IllegalArgumentException finalException = null; + for (final Constructor constructor : constructors) { + parameterTypes = constructor.getParameterTypes(); + values = ClassUtil.getDefaultValues(parameterTypes); + + try { + return (T) enhancer.create(parameterTypes, values); + } catch (final IllegalArgumentException e) { + //ignore + finalException = e; + } + } + if (null != finalException) { + throw finalException; + } + + throw new IllegalArgumentException("No constructor provided"); + } } diff --git a/hutool-extra/src/test/java/org/dromara/hutool/extra/aop/IssueI74EX7Test.java b/hutool-extra/src/test/java/org/dromara/hutool/extra/aop/IssueI74EX7Test.java index 38298de34..de8136115 100755 --- a/hutool-extra/src/test/java/org/dromara/hutool/extra/aop/IssueI74EX7Test.java +++ b/hutool-extra/src/test/java/org/dromara/hutool/extra/aop/IssueI74EX7Test.java @@ -12,6 +12,7 @@ package org.dromara.hutool.extra.aop; +import lombok.Data; import org.dromara.hutool.core.lang.Console; import org.dromara.hutool.extra.aop.aspects.SimpleAspect; import org.dromara.hutool.extra.aop.engine.ProxyEngine; @@ -19,55 +20,32 @@ import org.dromara.hutool.extra.aop.engine.jdk.JdkProxyEngine; import org.dromara.hutool.extra.aop.engine.spring.SpringCglibProxyEngine; import org.junit.jupiter.api.Test; -import java.lang.reflect.Method; -import java.util.Arrays; - public class IssueI74EX7Test { @Test void proxyTest() { final SmsBlend smsBlend = new SmsBlendImpl(1); final ProxyEngine engine = new JdkProxyEngine(); - engine.proxy(smsBlend, new SimpleAspect(){ - private static final long serialVersionUID = 1L; - - @Override - public boolean before(final Object target, final Method method, final Object[] args) { - Console.log("切面进入"); - return true; - } - - @Override - public boolean after(final Object target, final Method method, final Object[] args, final Object returnVal) { - Console.log("代理Object:"+target.toString()); - Console.log("代理方法:"+method.getName()); - Console.log("代理参数:"+ Arrays.toString(args)); - return super.after(target, method, args, returnVal); - } - }); + engine.proxy(smsBlend, new SimpleAspect()); } + /** + * https://gitee.com/dromara/hutool/issues/I74EX7
+ * Enhancer.create()默认调用无参构造,有参构造或者多个构造没有很好的兼容。 + * + */ @Test void cglibProxyTest() { final SmsBlend smsBlend = new SmsBlendImpl(1); final ProxyEngine engine = new SpringCglibProxyEngine(); - engine.proxy(smsBlend, new SimpleAspect(){ - private static final long serialVersionUID = 1L; + engine.proxy(smsBlend, new SimpleAspect()); + } - @Override - public boolean before(final Object target, final Method method, final Object[] args) { - Console.log("切面进入"); - return true; - } - - @Override - public boolean after(final Object target, final Method method, final Object[] args, final Object returnVal) { - Console.log("代理Object:"+target.toString()); - Console.log("代理方法:"+method.getName()); - Console.log("代理参数:"+ Arrays.toString(args)); - return super.after(target, method, args, returnVal); - } - }); + @Test + void cglibProxyWithoutConstructorTest() { + final SmsBlend smsBlend = new SmsBlendImplWithoutConstructor(); + final ProxyEngine engine = new SpringCglibProxyEngine(); + engine.proxy(smsBlend, new SimpleAspect()); } public interface SmsBlend{ @@ -76,7 +54,7 @@ public class IssueI74EX7Test { public static class SmsBlendImpl implements SmsBlend{ - private int status; + private final int status; public SmsBlendImpl(final int status) { this.status = status; @@ -87,4 +65,15 @@ public class IssueI74EX7Test { Console.log("sms send." + status); } } + + @Data + public static class SmsBlendImplWithoutConstructor implements SmsBlend{ + + private int status; + + @Override + public void send() { + Console.log("sms send." + status); + } + } } From c8d504bbbe9523a3083d7c9eac2c7b7f85255980 Mon Sep 17 00:00:00 2001 From: Looly Date: Thu, 25 May 2023 00:07:34 +0800 Subject: [PATCH 2/2] fix test --- .../extra/aop/engine/spring/SpringCglibProxyEngine.java | 4 +++- .../java/org/dromara/hutool/extra/aop/IssueI74EX7Test.java | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/hutool-extra/src/main/java/org/dromara/hutool/extra/aop/engine/spring/SpringCglibProxyEngine.java b/hutool-extra/src/main/java/org/dromara/hutool/extra/aop/engine/spring/SpringCglibProxyEngine.java index bae44dc6b..6d61d7500 100644 --- a/hutool-extra/src/main/java/org/dromara/hutool/extra/aop/engine/spring/SpringCglibProxyEngine.java +++ b/hutool-extra/src/main/java/org/dromara/hutool/extra/aop/engine/spring/SpringCglibProxyEngine.java @@ -39,7 +39,9 @@ public class SpringCglibProxyEngine implements ProxyEngine { } /** - * 创建代理对象 + * 创建代理对象
+ * https://gitee.com/dromara/hutool/issues/I74EX7
+ * 某些对象存在非空参数构造,则需遍历查找需要的构造完成代理对象构建。 * * @param 代理对象类型 * @param enhancer {@link Enhancer} diff --git a/hutool-extra/src/test/java/org/dromara/hutool/extra/aop/IssueI74EX7Test.java b/hutool-extra/src/test/java/org/dromara/hutool/extra/aop/IssueI74EX7Test.java index de8136115..ddb85434a 100755 --- a/hutool-extra/src/test/java/org/dromara/hutool/extra/aop/IssueI74EX7Test.java +++ b/hutool-extra/src/test/java/org/dromara/hutool/extra/aop/IssueI74EX7Test.java @@ -12,7 +12,7 @@ package org.dromara.hutool.extra.aop; -import lombok.Data; +import lombok.Setter; import org.dromara.hutool.core.lang.Console; import org.dromara.hutool.extra.aop.aspects.SimpleAspect; import org.dromara.hutool.extra.aop.engine.ProxyEngine; @@ -66,7 +66,7 @@ public class IssueI74EX7Test { } } - @Data + @Setter public static class SmsBlendImplWithoutConstructor implements SmsBlend{ private int status;