gpt4 book ai didi

java - cglib 创建的 spring bean 抛出 no such method 异常

转载 作者:行者123 更新时间:2023-12-01 09:54:31 24 4
gpt4 key购买 nike

我有几十个类,如下所示:

@Repository("jobProcessingDao")
@Transactional(readOnly = true)
public class JobProcessingDaoImpl extends BaseDaoImpl implements JobProcessingDao {
/*implementation interface methods*/
}

仅此一个发生异常(并且仅此一个是由 cglib 生成的)。

其实,为什么spring使用cglib代理而不是jdk呢?我的类实现了接口(interface),并且我相信我没有为 ProxyFactoryBeanproxyInterfaces 设置任何值。

无论如何,我从 DefaultGeneratorStrategy#generate 类以字节格式获取,这就是我实际得到的:

behemoth@Anechka ~ $ javap -c xf.class
Compiled from "<generated>"
public class package_name.dataaccesscomponent.impl.JobProcessingDaoImpl$$EnhancerByCGLIB$$f8ed98b3 extends package_name.dataaccesscomponent.impl.JobProcessingDaoImpl implements org.springframework.context.annotation.ConfigurationClassEnhancer$EnhancedConfiguration {
static void CGLIB$STATICHOOK2();
Code:
0: new #22 // class java/lang/ThreadLocal
3: dup
4: invokespecial #25 // Method java/lang/ThreadLocal."<init>":()V
7: putstatic #27 // Field CGLIB$THREAD_CALLBACKS:Ljava/lang/ThreadLocal;
10: iconst_0
11: anewarray #61 // class java/lang/Object
14: putstatic #49 // Field CGLIB$emptyArgs:[Ljava/lang/Object;
17: ldc #77 // String package_name.impl.JobProcessingDaoImpl$$EnhancerByCGLIB$$f8ed98b3
19: invokestatic #83 // Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;
22: astore_0
23: iconst_2
24: anewarray #85 // class java/lang/String
27: dup
28: iconst_0
29: ldc #86 // String destroy
31: aastore
32: dup
33: iconst_1
34: ldc #87 // String ()V
36: aastore
37: ldc #89 // String org.springframework.beans.factory.DisposableBean
39: invokestatic #83 // Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;
42: dup
43: astore_1
44: invokevirtual #93 // Method java/lang/Class.getDeclaredMethods:()[Ljava/lang/reflect/Method;
47: invokestatic #99 // Method net/sf/cglib/core/ReflectUtils.findMethods:([Ljava/lang/String;[Ljava/lang/reflect/Method;)[Ljava/lang/reflect/Method;
50: dup
51: iconst_0
52: aaload
53: putstatic #47 // Field CGLIB$destroy$10$Method:Ljava/lang/reflect/Method;
56: aload_1
57: aload_0
58: ldc #87 // String ()V
60: ldc #86 // String destroy
62: ldc #100 // String CGLIB$destroy$10
64: invokestatic #106 // Method net/sf/cglib/proxy/MethodProxy.create:(Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lnet/sf/cglib/proxy/MethodProxy;
67: putstatic #51 // Field CGLIB$destroy$10$Proxy:Lnet/sf/cglib/proxy/MethodProxy;
70: pop
71: return
72: return

final void CGLIB$destroy$10() throws java.lang.Exception;
Code:
0: aload_0
1: invokespecial #39 // Method package_name/dataaccesscomponent/impl/JobProcessingDaoImpl.destroy:()V
4: return

public final void destroy() throws java.lang.Exception;
Code:
0: aload_0
1: getfield #41 // Field CGLIB$CALLBACK_1:Lnet/sf/cglib/proxy/MethodInterceptor;
4: dup
5: ifnonnull 17
8: pop
9: aload_0
10: invokestatic #45 // Method CGLIB$BIND_CALLBACKS:(Ljava/lang/Object;)V
13: aload_0
14: getfield #41 // Field CGLIB$CALLBACK_1:Lnet/sf/cglib/proxy/MethodInterceptor;
17: dup
18: ifnull 37
21: aload_0
22: getstatic #47 // Field CGLIB$destroy$10$Method:Ljava/lang/reflect/Method;
25: getstatic #49 // Field CGLIB$emptyArgs:[Ljava/lang/Object;
28: getstatic #51 // Field CGLIB$destroy$10$Proxy:Lnet/sf/cglib/proxy/MethodProxy;
31: invokeinterface #57, 5 // InterfaceMethod net/sf/cglib/proxy/MethodInterceptor.intercept:(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;Lnet/sf/cglib/proxy/MethodProxy;)Ljava/lang/Object;
36: return
37: aload_0
38: invokespecial #39 // Method package_name/dataaccesscomponent/impl/JobProcessingDaoImpl.destroy:()V
41: return

public static net.sf.cglib.proxy.MethodProxy CGLIB$findMethodProxy(net.sf.cglib.core.Signature);
Code:
0: aload_0
1: invokevirtual #65 // Method java/lang/Object.toString:()Ljava/lang/String;
4: dup
5: invokevirtual #69 // Method java/lang/Object.hashCode:()I
8: tableswitch { // 1460027707 to 1460027707
1460027707: 28
default: 40
}
28: ldc #71 // String destroy()V
30: invokevirtual #75 // Method java/lang/Object.equals:(Ljava/lang/Object;)Z
33: ifeq 41
36: getstatic #51 // Field CGLIB$destroy$10$Proxy:Lnet/sf/cglib/proxy/MethodProxy;
39: areturn
40: pop
41: aconst_null
42: areturn

public package_name.dataaccesscomponent.impl.JobProcessingDaoImpl$$EnhancerByCGLIB$$f8ed98b3();
Code:
0: aload_0
1: dup
2: invokespecial #107 // Method package_name/dataaccesscomponent/impl/JobProcessingDaoImpl."<init>":()V
5: invokestatic #45 // Method CGLIB$BIND_CALLBACKS:(Ljava/lang/Object;)V
8: return

public static void CGLIB$SET_THREAD_CALLBACKS(net.sf.cglib.proxy.Callback[]);
Code:
0: getstatic #27 // Field CGLIB$THREAD_CALLBACKS:Ljava/lang/ThreadLocal;
3: aload_0
4: invokevirtual #112 // Method java/lang/ThreadLocal.set:(Ljava/lang/Object;)V
7: return

public static void CGLIB$SET_STATIC_CALLBACKS(net.sf.cglib.proxy.Callback[]);
Code:
0: aload_0
1: putstatic #115 // Field CGLIB$STATIC_CALLBACKS:[Lnet/sf/cglib/proxy/Callback;
4: return

static {};
Code:
0: invokestatic #131 // Method CGLIB$STATICHOOK2:()V
3: return
}

所以当我看到 cglibs 生成的类扩展了我的类时,这个类怎么可能没有这样的方法(在我的类中所有方法都是公共(public)的)?

异常:

Caused by: java.lang.NoSuchMethodError: pakcage_name.dataaccesscomponent.JobProcessingDao.save(Lpakcage_name/businessentities/JobProcessing;)J
at package_name.synchandler.impl.SyncHandlerImpl.createCompositeJobProcessing(SyncHandlerImpl.java:1232)

附注 Spring 3.1.0.RELEASE

最佳答案

我不能说我可以根据所提供的信息真正回答您的问题。但我可以说:

  • Jdk 代理比 CGLIB 代理更快

  • 不能为类创建 Jdk 代理,只能为接口(interface)创建。

  • Spring 将始终青睐 JDK 代理(因为它们显然更快:))。但如果无法创建 JDK 代理,它将使用 CGLIB。

因此,除非它不是 Spring 中的错误或其他问题,否则我认为您应该看看使用 JobProcessingDaoImpl 的类。很可能相关的数据字段不是通过接口(interface)连接的,而是通过类,所以 Spring 没有选择,它必须使用 CGLIB。

我认为您还应该检查运行时(使用调试器或其他东西)其他 DAO 实现 - 也许它们全部都用 JDK 代理包装。

关于java - cglib 创建的 spring bean 抛出 no such method 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37350166/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com