【问题标题】:Spring ApplicationContext.getBean(Class c) not working for proxy classesSpring ApplicationContext.getBean(Class c) 不适用于代理类
【发布时间】:2012-07-17 03:26:36
【问题描述】:

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

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

我对此有一个修复,但我并不想使用 Spring 的补丁版本,我怀疑我必须配置一些东西才能使其正常工作,或者这真的是一个错误吗?

【问题讨论】:

    标签: java spring proxy applicationcontext


    【解决方案1】:

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

    使用接口(默认)如果您的类实现了任何接口,Spring 将创建一个代理来实现所有这些接口。从现在开始,您只能通过该接口使用您的 bean。你的班级深深地埋在其中。

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

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

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

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

    另见

    【讨论】:

    • 感谢您的解释 - 我确实发现我可以通过接口检索我的 bean。我考虑过使用它,但问题是我绝对需要在我的情况下引用具体类(具体类还实现了我依赖的另一个接口)。我得出的结论是,我今天将使用 GCLIB 选项来解决它。为什么有人不想使用它?至于使用代理类,这对我来说像是一个错误,而不是一个“功能”!
    • @AlexWorden:如果您的类实现了多个接口,您可以通过其中任何一个来获取 bean。 CGLIB 的缺点之一是……您必须使用 CGLIB(外部库)。好吧,它既不是错误也不是特性——Spring 必须以某种方式实现 AOP,这是两个最常见的特性。此外,CGLIB 还有其他副作用,例如创建类的两个实例而不是一个。两个多评论
    【解决方案2】:
    <context:component-scan base-package="<Your base package name goes here>" />
    <aop:aspectj-autoproxy />
    <aop:config proxy-target-class="true"/>
    

    在 applicationContext.xml 中写这三行这对我有用。

    【讨论】:

      猜你喜欢
      • 2023-04-06
      • 1970-01-01
      • 1970-01-01
      • 2020-02-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-15
      相关资源
      最近更新 更多