java - Spring ApplicationContext.getBean(Class c) 不适用于代理类

标签 java spring proxy applicationcontext

我需要通过类类型查找 bean。当 beans 被代理包装时(一些方法是@Transactional)——ApplicatoinContext 找不到它们。我发现如果我通过接口(interface)查找它们,它就可以工作,但在这种情况下,我使用的是具体类类型。我知道这个 bean 是我正在寻找的类型,但是 getBean() 方法失败了。

我可以调试(并修复)Spring 的 AbstractBeanFactory 代码中的问题。问题是它根据我请求的类型检查 beanInstance 的类型,但 beanInstance.getClass() 是一个代理。 AbstractBeanFactory 应该对此进行补偿并将类型与代理的目标类进行比较。

我有一个修复程序,但我不是特别想使用 Spring 的补丁版本,我怀疑必须有一些我可以配置的东西才能让它工作,或者这真的是一个错误?

最佳答案

Spring 实现 AOP 有两种主要方式(例如 @Transactional 支持):使用代理接口(interface)或 CGLIB。

使用接口(interface)(默认),如果您的类实现任何接口(interface),Spring 将创建一个实现所有接口(interface)的代理。从现在开始,您只能通过该接口(interface)使用您的 bean。你的类(class)深深地埋在他们里面。

如果您改为通过 启用代理目标类:

<aop:config proxy-target-class="true">

Spring 将创建一个子类(显然仍然实现所有接口(interface))。这将解决您的问题。但是请记住,返回的对象实际上并不是您的类,而是动态生成的子类,它包装并委托(delegate)给您的原始对象。在大多数情况下,这应该不是问题。

不,当然这不是错误,而是众所周知的行为,不,不需要给 Spring 打补丁。

另见

关于java - Spring ApplicationContext.getBean(Class c) 不适用于代理类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11535527/

相关文章:

java - 使用抽象父类(super class)作为 Spring 数据存储库的参数

java - Android - 根据文件名获取文件的 R.raw.value?

java - 无法从静态上下文中引用非静态字段

python - 如何将来自服务器的响应作为缓存存储在磁盘上,以及如何使用 Python 中的套接字将该响应发送到 Web 浏览器

proxy - 在防火墙后面时,如何在 Windows 上使用 rustup 安装 Rust?

通过 https 更新 Git 子模块

java - 由于 OSX 中的其他线程,Platform.exit() 未结束 Javafx

java - 来自服务器 [200] 的 HTTP 响应不允许 HTTP 升级到 WebSocket

java - 找不到获取 Spring bean 方法参数的参数化类型的方法

spring - 将日期传递给 Oracle Select 查询中的 NamedParameterJdbcTemplate