2012-08-28 43 views
0

我有一个3层应用程序:web服务,服务层和域层。 Web服务存在于Web应用程序(WAR)中。服务层和域层是两个JAR项目。依赖项:依赖项的类路径扫描

网络服务 - >服务层 - >域层

在服务层,服务被注解为@Service。在域层中,DAO注释为@Repository。 Web服务实现类使用服务层JAR的服务,因此它将自动注入每个服务的一个实例(@Autowired)。

依赖关系在我的POM中已经有很好的定义。当我部署我在Tomcat WAR,我得到以下异常:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.mycompany.project.services.MyService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {} 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:952) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:821) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:735) 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:551) 
    ... 37 more 

我从一个相关部分引用在Spring文档:

类路径包的扫描需要的 对应的目录存在类路径中的条目。当您使用Ant构建JAR文件 时,请确保您没有激活JAR任务的文件专用开关 。

我已检查并且服务层JAR存在于WEB-INF/lib目录中。

有什么想法?

感谢


编辑:我有位于src/main/webapp/WEB-INF下的web服务层项目(WAR)只有一个上下文文件。在这种情况下,我已经启用的classpath扫描如下:

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

com.mycompany.project是我的项目的基础包,其下有web服务(com.mycompany.project.server),服务层(com.mycompany.project.services)和域层(com.mycompany.project.domain)包。

我已经解决了这个问题。我不明白为什么我所做的是造成这样的问题。每个服务实现一个定义其公共方法的接口。在我的Web服务实现类中,对服务的引用使用实现类而不是接口。我只是改变他们使用的界面,我不再有问题了。任何人都可以解释我使用服务实现类而不是自动装配的接口有什么问题吗?

+0

很多事情都可能发生在这里。一种可能的可能性是您的Web层上下文不知道有关服务层上下文的任何信息。或者你没有在服务层上下文中进行组件扫描。要回答这些问题,您需要发布您的上下文文件。 – parsifal

+0

请发布配置组件扫描的弹簧配置的一部分。 – Ralph

+0

另请参阅:查看例外报告的*结尾*。 Spring会递归地报告bean实例化失败,并且报告中的最后一个bean是问题所在(它阻止在报告中更高级地实例化任何bean)。 – parsifal

回答

0

你可以显示你的组件扫描配置吗?如果设置不正确,Spring可能不会发现您的服务。

你想要的东西,如:

<context:component-scan base-package="your.service.package"/> 

编辑:

我认为问题是,你的@Service注释是接口,而不是实现类。

如果注释服务实现将您的网络控制器可以使用:

@Autowired 
private ExampleService service; 

@Autowired 
private ExampleServiceImpl service; 
+0

我编辑了我的问题。 –

+0

关于我对编辑的回答,@Service注释被放置在实现类上,而不是在接口上。 –

0
  1. 确保您使用<context:component-scan base-package="your.service.package"/>
  2. 检查你的自动装配Autowired策略是byNamebyType;如果byNameService注释的名称值应该是正确的。
  3. 如果问题仍然存在,请检查spring的日志,它会打印所有找到的组件的名称,您可以知道服务是否成立。
+0

我编辑了我的问题。我已经在基础包(它应该包含包含我的服务的包)上启用类路径扫描。我没有在服务注释中指定名称,但默认情况下,Spring采用相同的名称,但第一个字母为小写。 –

2

这是您的编辑答案:

之所以提到工作的接口,但具体实施失败的原因是可能与春天创建,你有带注释的服务情况下,dynamic proxies@Transactional等。在这种情况下会发生什么情况是您的bean的类型不再是实现类型,而是环绕您的强制类型。所以当你通过实现类型拥有@Autowired时,它就不能通过类型找到它(这是默认值)。

由于动态代理继续从您为实现定义的接口派生,因此可以通过接口类型注入 - 我提供的参考可以更好地解释此问题,因此您的解决方案非常合适。

相关问题