[英]Spring @autowired do not work if all classes are not in the same package
我有四个包:
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
我将所有控制器类放在com.spring.org包中,其他包基于其类型放在不同的包中。 如果我运行我的应用程序,我收到此错误消息:
HTTP状态500 - servlet appServlet的Servlet.init()抛出异常 没有找到依赖的类型[com.spring.org.service.SubscriberService]的限定bean:预期至少有一个bean有资格作为此依赖关系的autowire候选者... ..
仅供参考:我在我的控制器中使用自动装载的annoation,如下所示:
@Autowired
private SubscriberService subService;
但是,如果我将所有类和接口放在com.spring.org包中,那么我的应用程序就可以完美运行。
我已经尝试在我的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" />
我也只尝试过这个:
<context:component-scan base-package="com.spring.org" />
你可以在这里看到我的servlet-context.xml文件的代码http://postimg.org/image/s6bnjccrn/
你能告诉我如何解决这个问题吗?
如果您需要查看任何其他文件,请告诉我。
我的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);
}
根本原因
org.springframework.beans.factory.BeanCreationException:创建名为'homeController'的bean时出错:注入自动连接的依赖项失败; 嵌套异常是org.springframework.beans.factory.BeanCreationException:无法自动装配字段:private com.spring.service.SubscriberService com.spring.org.HomeController.subService; 嵌套异常是org.springframework.beans.factory.NoSuchBeanDefinitionException:找不到[com.spring.service.SubscriberService]类型的限定bean用于依赖:预期至少有1个bean可以作为此依赖项的autowire候选者。 依赖注释:{@ 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)
如果我在这里粘贴所有代码,那将非常难以理解,所以我在这里上传了我的整个项目https://www.mediafire.com/?crxe7vt7uwyqwtl 。 我正在使用Eclipse IDE。
你的结构应该是这样的
订阅服务接口
package com.spring.org.service;
public interface SubscriberService {
}
SubscriberServiceImpl.java
package com.spring.org.service;
@Component
@Qualifier("Subscriber")
public class SubscriberServiceImpl implements SubscriberService {
}
'SubscriberServiceImpl1'是一个组件,它实现了'SubscriberService'。
SubscriberServiceImpl1.java
package com.spring.org.service;
@Component
@Qualifier("Subscriber1")
public class SubscriberServiceImpl1 implements SubscriberService {
}
我设置了一个Spring上下文,它扫描这两个包中标有'@Component'的bean。
servlet的context.xml中
<annotation-driven />
<context:annotation-config />
<context:component-scan base-package="com.spring"/>
HomeController.java
@Controller
public class HomeController {
@Autowired
@Qualifier("Subscriber")
private SubscriberService subService;
}
请参阅此链接 。 希望对你有帮助....
编辑
根据您的包结构,您的SubscriberServiceImpl类位于包com.spring.org.service下,只需使用com.spring更改您的基本包,这将适合您
<context:component-scan base-package="com.spring"/>
问题是您有多个SubscriberService
接口的实现。
当您编写以下代码时:
@Autowired
private SubscriberService subService;
Spring将寻找SubscriberService
的实现,因为你将有多个实现,spring将不知道要注入哪个实现。
解决方案是使用@Qualifier
来区分不同的实现。
有关@Qualifier
更多信息和演示,请访问此链接。
或者,如果您有一个SubscriberService
实现,请确保服务和实现都属于您在spring上下文中提供的扫描包。
希望能帮助到你。
您只需指定基础包:
<context:component-scan base-package="com.spring.org"/>
我相信你应该注释实现类而不是接口。
尝试使用逗号分隔包,如下所示:
<context:component-scan
base-package="com.spring.org,com.spring.org.dao,com.spring.org.model,com.spring.org.service" />
尝试在SubscriberServiceImpl上添加@Component。
基本上注释如@ Service,@ Repository,@ Component等,它们都有相同的用途:
使用基于注释的配置和类路径扫描时自动检测。
根据我的经验,我总是在接口或抽象类和注释(如@Component和@Repository)上使用@Service注释来实现它们。 @Component注释我在那些用于基本目的的类上使用,简单的Spring bean,仅此而已。 我正在DAO层中使用的@Repository注释,例如,如果我必须与数据库通信,进行一些事务等。
如下指定基本扫描并从接口中删除注释,并仅保留在实现类中,例如@ Service,@ Repository,@ Component等。
<context:component-scan base-package="com.spring.org"/>
编辑:
我查看了你的代码。你已经将组件扫描为
但是您的SubscriberService.java位于com.spring.service包中。 请将软件包更改为com.spring.org.service。
首先,您必须将此标记放在XML(应用程序上下文文件)中:
<context:component-scan base-package="com.spring.org"/>
为了解决这个问题,你需要改变这个:
@Autowired
@Qualifier("Subscriber")
private SubscriberService subService
因为Spring会搜索SubscriberService
类型的bean(在你的例子中),如果它找到了这样的bean,它会将它注入到这个方法中。 如果它找到两个这样的bean,你将得到一个Exception(它与你的堆栈跟踪中的相同)。
如果您不想使用两个注释( @Autowired
和@Qualifier
),您可以使用@Resource
来组合这两个:
@Resource(name="redBean")
private SubscriberService subService
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.