Java 如果所有类都不在同一个包中,则 Spring @autowired 不起作用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25683627/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring @autowired do not work if all classes are not in the same package
提问by black_belt
I have four packages:
我有四个包:
com.spring.org
Files:
HomeController.java
com.spring.org.dao
Files:
SubscriberDao.java
,SubscriberDaoImpl.java
com.spring.org.model
Files:
Subscriber.java
com.spring.org.service
Files:
SubscriberService.java
,SubscriberServiceImpl.java
com.spring.org
文件:
HomeController.java
com.spring.org.dao
文件:
SubscriberDao.java
,SubscriberDaoImpl.java
com.spring.org.model
文件:
Subscriber.java
com.spring.org.service
文件:
SubscriberService.java
,SubscriberServiceImpl.java
I put all my controller classes in com.spring.orgpackage and others in different packages based on its type. If I run my application I get this error message :
我将所有控制器类放在com.spring.org包中,其他类根据其类型放在不同的包中。如果我运行我的应用程序,我会收到此错误消息:
HTTP Status 500 - Servlet.init() for servlet appServlet threw exceptionNo qualifying bean of type [com.spring.org.service.SubscriberService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency.....
HTTP 状态 500 - servlet appServlet 的 Servlet.init() 抛出异常未找到类型为 [com.spring.org.service.SubscriberService] 的合格 bean 依赖项:预计至少有 1 个 bean 有资格作为此依赖项的自动装配候选... ..
FYI: I am using autowired annoation in my Controller like following:
仅供参考:我在我的控制器中使用自动装配注释,如下所示:
@Autowired
private SubscriberService subService;
But if I put all my classes and interfaces in com.spring.orgpackage then my application works perfectly.
但是如果我把所有的类和接口都放在com.spring.org包中,那么我的应用程序就可以完美运行。
I have tried using these tags in my servlet-context.xml file to solve the problem, but still it did not work:
我已经尝试在我的 servlet-context.xml 文件中使用这些标签来解决问题,但它仍然不起作用:
<annotation-driven />
<context:annotation-config />
<context:component-scan base-package="com.spring.org.**" />
<context:component-scan base-package="com.spring.org.dao" />
<context:component-scan base-package="com.spring.org.model" />
<context:component-scan base-package="com.spring.org.service" />
I also tried only this:
我也只试过这个:
<context:component-scan base-package="com.spring.org" />
You can see the code of my servlet-context.xml file here http://postimg.org/image/s6bnjccrn/
你可以在这里看到我的 servlet-context.xml 文件的代码http://postimg.org/image/s6bnjccrn/
Could you please tell me how to solve this problem ?
你能告诉我如何解决这个问题吗?
Please let me know if you need to see any other files.
如果您需要查看任何其他文件,请告诉我。
Update
更新
My Code for SubscriberService :
我的 SubscriberService 代码:
@Service
public interface SubscriberService {
public void addSubscriber(Subscriber subscriber);
public void updateSubscriber(Subscriber subscriber);
public Subscriber getSubscriberById(int subId);
public List<Subscriber> listSubs();
public int removeSubscriber(int subId);
}
Root Cause
根本原因
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'homeController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.spring.service.SubscriberService com.spring.org.HomeController.subService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.spring.service.SubscriberService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=)} org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:292)
org.springframework.beans.factory.BeanCreationException:创建名为“homeController”的 bean 时出错:自动装配依赖项的注入失败;嵌套异常是 org.springframework.beans.factory.BeanCreationException:无法自动装配字段:私有 com.spring.service.SubscriberService com.spring.org.HomeController.subService; 嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinitionException: 找不到类型为 [com.spring.service.SubscriberService] 的合格 bean 依赖项:预期至少有 1 个 bean 有资格作为此依赖项的自动装配候选者。依赖注解:{@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=)} org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor .
Files
文件
It would be very difficult to follow if I paste all my codes here, so I have upload my entire project here https://www.mediafire.com/?crxe7vt7uwyqwtl. I am using Eclipse IDE.
如果我将所有代码粘贴在这里,将很难遵循,因此我将整个项目上传到这里https://www.mediafire.com/?crxe7vt7uwyqwtl。我正在使用 Eclipse IDE。
采纳答案by Ashish Jagtap
your structure should be like this
你的结构应该是这样的
SubscriberService Interface
订阅者服务接口
package com.spring.org.service;
public interface SubscriberService {
}
SubscriberServiceImpl.java
SubscriberServiceImpl.java
package com.spring.org.service;
@Component
@Qualifier("Subscriber")
public class SubscriberServiceImpl implements SubscriberService {
}
‘SubscriberServiceImpl1' is a component and it implements ‘SubscriberService'.
'SubscriberServiceImpl1' 是一个组件,它实现了 'SubscriberService'。
SubscriberServiceImpl1.java
SubscriberServiceImpl1.java
package com.spring.org.service;
@Component
@Qualifier("Subscriber1")
public class SubscriberServiceImpl1 implements SubscriberService {
}
I setup a Spring context that scans both of these packages for beans marked with ‘@Component'.
我设置了一个 Spring 上下文来扫描这两个包中标有“@Component”的 bean。
servlet-context.xml
servlet-context.xml
<annotation-driven />
<context:annotation-config />
<context:component-scan base-package="com.spring"/>
HomeController.java
主控制器.java
@Controller
public class HomeController {
@Autowired
@Qualifier("Subscriber")
private SubscriberService subService;
}
refer from this link. hope this will help you....
从这个链接参考。希望能帮到你....
EDIT
编辑
as per your package structure your SubscriberServiceImplclass is under package com.spring.org.servicejust change your base package with com.springthis will work for you
根据您的包结构,您的SubscriberServiceImpl类位于包com.spring.org.service 下,只需使用com.spring更改您的基本包,这对您有用
<context:component-scan base-package="com.spring"/>
回答by villager
You just need to specify the base package:
您只需要指定基本包:
<context:component-scan base-package="com.spring.org"/>
I believe you should annotate the implementation class instead of the interface.
我相信你应该注释实现类而不是接口。
回答by Darshan Lila
The problem is you are having multiple implementation of SubscriberService
interface.
问题是您有多个SubscriberService
接口实现。
When you write following code:
当您编写以下代码时:
@Autowired
private SubscriberService subService;
Spring will look for an implementation of SubscriberService
, and since you would be having multiple implementation for it spring will not know which implementation to inject.
Spring 将寻找 的实现SubscriberService
,并且由于您将有多个实现,因此 spring 将不知道要注入哪个实现。
Solution to this is using @Qualifier
to differentiate between different implementations.
对此的解决方案是使用@Qualifier
区分不同的实现。
For more and for a demo on @Qualifier
visit thislink.
有关更多信息和演示,@Qualifier
请访问此链接。
Alternatively if you're having a single implementation for SubscriberService
make sure both the service and implementation fall under the packages you provide for scan in spring context.
或者,如果您有一个单一的实现,SubscriberService
以确保服务和实现都属于您在 spring 上下文中为扫描提供的包。
Hope it helps.
希望能帮助到你。
回答by R_J
Try comma-separating the packages, like this:
尝试用逗号分隔包,如下所示:
<context:component-scan
base-package="com.spring.org,com.spring.org.dao,com.spring.org.model,com.spring.org.service" />
回答by Xstian
Try to add @Component on SubscriberServiceImpl.
尝试在 SubscriberServiceImpl 上添加 @Component。
Basically annotations like @Service, @Repository, @Component, etc. they all serve the same purpose:
基本上像@Service、@Repository、@Component 等注解,它们都用于相同的目的:
auto-detection when using annotation-based configuration and classpath scanning.
使用基于注解的配置和类路径扫描时的自动检测。
From my experience I am always using @Service annotation on the interfaces or abstract classes and annotations like @Component and @Repository for their implementation. @Component annotation I am using on those classes which serves basic purposes, simple Spring beans, nothing more. @Repository annotation I am using in the DAO layer, for e.g. if I have to communicate to the database, have some transactions, etc.
根据我的经验,我总是在接口或抽象类上使用 @Service 注释,并使用 @Component 和 @Repository 等注释来实现它们。@Component 注释我在那些服务于基本目的的类上使用,简单的 Spring bean,仅此而已。我在 DAO 层中使用的 @Repository 注释,例如,如果我必须与数据库通信,进行一些事务等。
回答by m b
Specify the base scan as follows and remove the annotation from interface and keep only in the implementation class e.g. @Service, @Repository, @Component, etc.
如下指定基本扫描,并从接口中删除注释,只保留在实现类中,例如@Service、@Repository、@Component 等。
<context:component-scan base-package="com.spring.org"/>
EDIT:
编辑:
I looked into your code.You have given your component scan as
我查看了您的代码。您已将您的组件扫描为
But your SubscriberService.java is in the package com.spring.service. Kindly change the package to com.spring.org.service.
但是您的 SubscriberService.java 在包 com.spring.service 中。请将包更改为 com.spring.org.service。
回答by Seif Tamallah
First you have to put this tag in your XML (application context file):
首先,您必须将此标记放在您的 XML(应用程序上下文文件)中:
<context:component-scan base-package="com.spring.org"/>
To fix the expection you got you have to change this :
要解决您的期望,您必须更改此内容:
@Autowired
@Qualifier("Subscriber")
private SubscriberService subService
because Spring searches for a bean of type SubscriberService
(in your case), and if it finds such bean, it injects it to this method. If it finds two such beans you will get an Exception ( it is the same one in your stack trace).
因为 Spring 搜索类型为SubscriberService
(在您的情况下)的 bean,如果找到这样的 bean,它会将其注入此方法。如果它找到两个这样的 bean,你会得到一个异常(它在你的堆栈跟踪中是同一个)。
f you don't want to use two annotations (the @Autowired
and @Qualifier
) you can use @Resource
to combine these two:
如果您不想使用两个注释(@Autowired
和@Qualifier
),您可以@Resource
将这两个注释结合起来:
@Resource(name="redBean")
private SubscriberService subService