【问题标题】:Spring @autowired do not work if all classes are not in the same package如果所有类不在同一个包中,则 Spring @autowired 不起作用
【发布时间】:2014-09-05 10:17:45
【问题描述】:

我有四个包:

  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

我将所有控制器类放在 com.spring.org 包中,而其他控制器类则根据其类型放在不同的包中。如果我运行我的应用程序,我会收到以下错误消息:

HTTP 状态 500 - Servlet appServlet 的 Servlet.init() 抛出异常 没有为依赖找到类型为 [com.spring.org.service.SubscriberService] 的合格 bean:预计至少有 1 个 bean 有资格作为此依赖的自动装配候选者.....

仅供参考:我在控制器中使用自动连线注释,如下所示:

@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:无法自动装配字段:私有 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.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:292)

文件

如果我把所有的代码都贴在这里会很难理解,所以我把我的整个项目上传到这里https://www.mediafire.com/?crxe7vt7uwyqwtl。我正在使用 Eclipse IDE。

【问题讨论】:

  • 问题可能不在于扫描或配置。请发布com.spring.org.service.SubscriberService 的代码及其实现。
  • 感谢您的回复,请查看我问题的更新部分
  • 对于初学者来说,你的基础包是错误的,删除.**。还要确保将注释放在实现而不是接口上。如果它在接口上,则不会发生任何事情(这就是注释的本质,它们不会从接口继承到类!)。
  • @M.Deinum 我尝试删除 .** 但它不起作用。而且我的接口和实现类中都有注释
  • 请添加您的 SubscirberDao.java 、 SubscirberDaoImpl.java 和 HomeController.java 的整个代码,以便我们了解问题的原因...

标签: java spring spring-mvc


【解决方案1】:

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

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

编辑:

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

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

【讨论】:

  • 如果可能,请尝试删除以下代码 因为它是 context:component-scan 的子集
【解决方案2】:

你的结构应该是这样的

订阅者服务接口

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"/>

【讨论】:

  • 感谢您的回复。我已经在 mediafire.com/?crxe7vt7uwyqwtl 上传了我的整个项目。我正在使用 Eclipse IDE。请你看一遍并告诉我我在哪里做错了。再次感谢。
  • 您在不同包中的服务层,它位于 com.spring.service 包下,并且您指定 com.spring.org 基本包,只需更改以下行 这对你有用...
【解决方案3】:

问题是您有多个SubscriberService 接口实现。

当你编写以下代码时:

@Autowired
private SubscriberService subService;

Spring 将寻找SubscriberService 的实现,并且由于您将有多个实现,因此 Spring 将不知道要注入哪个实现。

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

欲了解更多信息和@Qualifier 上的演示,请访问this 链接。

或者,如果您有一个 SubscriberService 的实现,请确保服务和实现都属于您提供的用于在 spring 上下文中扫描的包。

希望对你有帮助。

【讨论】:

  • 感谢您的回复。我只有一个 SubscriberService 的实现
  • 还是试试限定符。
  • 请贴出你要自动装配的类的代码SubscriberService及其实现类。
  • 我已经在mediafire.com/?crxe7vt7uwyqwtl 上传了我的整个项目。我正在使用 Eclipse IDE。非常感谢您的帮助:)
  • 我查看了您的代码。服务层不属于组件扫描,为其添加组件扫描或将其移动到 com.spring.org
【解决方案4】:

你只需要指定基础包:

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

我认为你应该注释实现类而不是接口。

【讨论】:

  • 我的接口和实现类都有注释
【解决方案5】:

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

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

【讨论】:

  • 感谢您的回复。我刚刚尝试了您的代码,但它不起作用
【解决方案6】:

尝试在 SubscriberServiceImpl 上添加@Component。

@Service、@Repository、@Component 等注解基本上都有相同的用途:

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

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

【讨论】:

    【解决方案7】:

    首先,您必须将此标签放入您的 XML(应用程序上下文文件)中:

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

    要解决你得到的期望,你必须改变这个:

    @Autowired
    @Qualifier("Subscriber")
    private SubscriberService subService
    

    因为 Spring 搜索类型为 SubscriberService 的 bean(在您的情况下),如果找到这样的 bean,它会将其注入此方法。如果它找到两个这样的 bean,你会得到一个异常(它在你的堆栈跟踪中是同一个)。

    如果您不想使用两个注释(@Autowired@Qualifier),您可以使用 @Resource 将这两个注释组合起来:

    @Resource(name="redBean")
    private SubscriberService subService
    

    【讨论】:

      猜你喜欢
      • 2016-03-25
      • 2018-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多