实现新接口时出现NoSuchBeanDefinitionException

时间:2010-11-06 04:38:00

标签: java spring

我有以下设置完美无缺:

@Service
public class MyService {
}

public class Test {
   @Autowired
   MyService service;
}

我更改了MyService以实现一个新的界面,比如

@Service
public class MyService implements NewInterface {
}

这个界面没有什么特别之处,它只是一个没有任何注释的普通Java界面和2个非常简单的方法。

现在,Spring不再能够自动装配这个bean了,它提供了NoSuchBeanDefinitionException。我也尝试在XML中明确定义它,但它给出了相同的例外。

如果它是相关的,我使用Spring 2.5并使用Maven构建,类Test是一个单元测试类。当我尝试运行真正的应用程序时,它使用applicationContext.getBean()来获取此服务,并且它提供以下异常:java.lang.ClassCastException: $Proxy81 cannot be cast to MyService

我错过了什么,我该怎么做?

2 个答案:

答案 0 :(得分:3)

看起来你是通过界面自动装配而不是通过类名自动装配。

我只是根据界面编写测试代码:

public class Test {
   @Autowired
   NewInterface service;
}

另外,请检查this bug,它可能与您相关,因为它似乎代表您的课程。

答案 1 :(得分:3)

当你看到一个名为$Proxy81的类时,它会告诉你Spring为你的一个bean自动生成了一个代理对象,在这种情况下是MyService bean的代理对象。这使用java.lang.reflect.Proxy生成代理对象。此代理对象将实现与被代理的类相同的接口,但它不会与目标类本身类型兼容。

现在,如果目标类没有实现任何接口,那么Spring将使用CGLIB来生成代理。此代理将是目标类的子类,因此代理对象可以安全地转换为目标对象的原始类型。

现在,当在Spring中使用较低级别的代理生成内容时,您通常可以覆盖此行为,并告诉它始终使用CGLIB代理,但我假设您使用@Service ,那么你也使用<context:component-scan>,在这种情况下,我认为你必须坚持默认行为。

但是,这不是坏事。这鼓励您不要将您的课程结合在一起,而是编程到接口。与MyService的任何交互都应该通过接口表达,尽管在讨论单元测试时这个概念可能会有点模糊。