简体   繁体   English

实现新接口时出现NoSuchBeanDefinitionException

[英]NoSuchBeanDefinitionException when implementing a new interface

I had the following set-up which worked perfectly fine: 我进行了以下设置,效果很好:

@Service
public class MyService {
}

public class Test {
   @Autowired
   MyService service;
}

I changed MyService to implement a new interface, like this 我改变了MyService来实现一个新的接口,像这样

@Service
public class MyService implements NewInterface {
}

There's nothing special in this interface, it's just a normal Java interface without any annotation and 2 very simple methods. 该接口没有什么特别的,它只是一个普通的Java接口,没有任何注释和2个非常简单的方法。

Now, Spring is not able to autowire this bean anymore, it gives a NoSuchBeanDefinitionException . 现在,Spring不再能够自动装配该bean,它提供了NoSuchBeanDefinitionException I also tried to define it explicitly in the XML but it gave the same exception. 我也尝试在XML中显式定义它,但是它给出了相同的例外。

In case it's relevant, I'm using Spring 2.5 and build with Maven, the class Test is a unit test class. 如果相关,我将使用Spring 2.5并使用Maven进行构建,Test类是单元测试类。 When I try to run the real application, it's using applicationContext.getBean() to get this service, and it gives the following exception: java.lang.ClassCastException: $Proxy81 cannot be cast to MyService . 当我尝试运行真实的应用程序时,它正在使用applicationContext.getBean()获取此服务,并且它给出以下异常: java.lang.ClassCastException: $Proxy81 cannot be cast to MyService

What am I missing and what should I do? 我想念什么,我该怎么办?

It looks like you're autowiring by interface instead of autowiring by class name. 看起来您是通过接口自动装配,而不是通过类名自动装配。

I'd simply code my test against the Interface: 我只是针对接口编写测试代码:

public class Test {
   @Autowired
   NewInterface service;
}

Also, check this bug , it might be relevant to you since it appears like your class is being proxied. 另外,请检查此bug ,它可能与您有关,因为它看起来像是您的课程正在被代理。

When you see a class with a name like $Proxy81 , it's telling you that Spring has auto-generated a proxy object for one of your beans, in this case a proxy object for the MyService bean. 当您看到一个名称类似于$Proxy81的类时,它告诉您Spring已自动为您的一个bean生成了一个代理对象,在本例中为MyService bean的代理对象。 This uses java.lang.reflect.Proxy to generate the proxy object. 这使用java.lang.reflect.Proxy生成代理对象。 This proxy object will implement the same interfaces as the class that's being proxied, but it will not be type-compatible with the target class itself. 该代理对象将实现与要代理的类相同的接口,但与目标类本身的类型不兼容。

Now, if the target class doesn't implement any interfaces, then Spring will instead use CGLIB to generate the proxy. 现在,如果目标类没有实现任何接口,那么Spring将改为使用CGLIB生成代理。 This proxy will be a subclass of the target class, so the proxy object can be safely cast to the original type of the target object. 该代理将是目标类的子类,因此可以将代理对象安全地强制转换为目标对象的原始类型。

Now, when using the lower-level proxy-generation stuff in Spring, you can often override this behaviour, and tell it to always use CGLIB proxies, but I'm assuming that since you're using @Service , then you're also using <context:component-scan> , in which case I think you have to stick with the default behaviour. 现在,当在Spring中使用较低级别的代理代产品时,您通常可以覆盖此行为,并告诉它始终使用CGLIB代理,但是我假设由于您正在使用@Service ,所以您也使用<context:component-scan> ,在这种情况下,我认为您必须坚持默认行为。

It's not bad thing, though. 不过,这不是一件坏事。 This encourages you to not couple your classes together, but instead to program to interfaces. 这鼓励您不要将类耦合在一起,而要编程为接口。 Any interaction with MyService should be expressible via interfaces, although this concept can get a little fuzzy when talking about unit testing. MyService任何交互都应该通过接口来表达,尽管在谈论单元测试时这个概念可能会有些模糊。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM