繁体   English   中英

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

[英]Spring @autowired do not work if all classes are not in the same package

我有四个包:

  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:预期至少有一个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.

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