如果所有类不在同一个包中,则Spring @autowired不起作用

时间:2014-09-05 10:17:45

标签: java spring spring-mvc

我有四个包:

  1. com.spring.org

    文件:HomeController.java

  2. com.spring.org.dao

    文件:SubscriberDao.javaSubscriberDaoImpl.java

  3. com.spring.org.model

    文件:Subscriber.java

  4. com.spring.org.service

    文件:SubscriberService.javaSubscriberServiceImpl.java

  5. 我将所有控制器类放在 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:使用名称&#39; homeController&#39;创建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。

7 个答案:

答案 0 :(得分:3)

问题是您正在多次实现SubscriberService接口。

当您编写以下代码时:

@Autowired
private SubscriberService subService;

Spring将寻找SubscriberService的实现,因为你将有多个实现,spring将不知道要注入哪个实现。

解决方案是使用@Qualifier来区分不同的实现。

有关@Qualifier访问this链接的详情和演示。

或者,如果您对SubscriberService实施单一实施,请确保服务和实施都属于您在春季环境中提供扫描的软件包。

希望它有所帮助。

答案 1 :(得分:3)

你的结构应该是这样的

SubscriberService Interface

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;

}

请参阅此 link 。 希望这会对你有帮助....

修改

根据您的包结构, SubscriberServiceImpl 类位于包 com.spring.org.service 下使用 com.spring 更改您的基本软件包这对您有用

<context:component-scan base-package="com.spring"/>

答案 2 :(得分:0)

您只需指定基础包:

<context:component-scan base-package="com.spring.org"/>

我相信你应该注释实现类而不是接口。

答案 3 :(得分:0)

尝试使用逗号分隔包,如下所示:

<context:component-scan 
base-package="com.spring.org,com.spring.org.dao,com.spring.org.model,com.spring.org.service" />

答案 4 :(得分:0)

尝试在SubscriberServiceImpl上添加@Component。

基本上注释如@ Service,@ Repository,@ Component等,它们都有相同的用途:

  

使用基于注释的配置和类路径时的自动检测   扫描。

根据我的经验,我总是在接口或抽象类和注释(如@Component和@Repository)上使用@Service注释来实现它们。 @Component注释我在那些用于基本目的的类上使用,简单的Spring bean,仅此而已。我正在DAO层中使用的@Repository注释,例如如果我必须与数据库进行通信,进行一些交易等等。

答案 5 :(得分:0)

如下指定基本扫描并从界面中删除注释,并仅保留在实现类中,例如@ Service,@ Repository,@ Component等

<context:component-scan base-package="com.spring.org"/> 

修改

我查看了您的代码。您已将组件扫描为

但您的SubscriberService.java位于com.spring.service包中。请将软件包更改为com.spring.org.service。

答案 6 :(得分:0)

首先,您必须将此标记放在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