我有以下设置完美无缺:
@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
。
我错过了什么,我该怎么做?
答案 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
的任何交互都应该通过接口表达,尽管在讨论单元测试时这个概念可能会有点模糊。