@Autowired - 没有为依赖找到符合条件的 bean
Posted
技术标签:
【中文标题】@Autowired - 没有为依赖找到符合条件的 bean【英文标题】:@Autowired - No qualifying bean of type found for dependency 【发布时间】:2013-12-18 10:44:18 【问题描述】:我通过使用 Spring 和 Hibernate 为服务创建实体、服务和 JUnit 测试来开始我的项目。所有这一切都很好。
然后我添加了 spring-mvc 来使用许多不同的分步教程制作这个 Web 应用程序,但是当我尝试使用 @Autowired
注释制作控制器时,我在部署期间从 Glassfish 收到错误。我猜出于某种原因,Spring 看不到我的服务,但经过多次尝试我仍然无法处理它。
服务测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:/beans.xml")
和
@Autowired
MailManager mailManager;
正常工作。
控制器也没有@Autowired
,我可以在网络浏览器中毫无问题地打开我的项目。
/src/main/resources/beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_2_0.xsd">
<context:property-placeholder location="jdbc.properties" />
<context:component-scan base-package="pl.com.radzikowski.webmail">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<!--<context:component-scan base-package="pl.com.radzikowski.webmail.service" />-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="$jdbc.driverClassName" />
<property name="url" value="$jdbc.url" />
<property name="username" value="$jdbc.username" />
<property name="password" value="$jdbc.password" />
</bean>
<!-- Persistance Unit Manager for persistance options managing -->
<bean id="persistenceUnitManager" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
<property name="defaultDataSource" ref="dataSource"/>
</bean>
<!-- Entity Manager Factory for creating/updating DB schema based on persistence files and entity classes -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitManager" ref="persistenceUnitManager"/>
<property name="persistenceUnitName" value="WebMailPU"/>
</bean>
<!-- Hibernate Session Factory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!--<property name="schemaUpdate" value="true" />-->
<property name="packagesToScan" value="pl.com.radzikowski.webmail.domain" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.mysqlDialect</prop>
</props>
</property>
</bean>
<!-- Hibernate Transaction Manager -->
<bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<!-- Activates annotation based transaction management -->
<tx:annotation-driven transaction-manager="txManager"/>
</beans>
/webapp/WEB-INF/web.xml
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="WebApp_ID" version="2.4" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Spring Web MVC Application</display-name>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
/webapp/WEB-INF/mvc-dispatcher-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<context:component-scan base-package="pl.com.radzikowski.webmail" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
pl.com.radzikowski.webmail.service.AbstractManager
package pl.com.radzikowski.webmail.service;
import org.apache.log4j.Logger;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Master Manager class providing basic fields for services.
* @author Maciej Radzikowski <maciej@radzikowski.com.pl>
*/
public class AbstractManager
@Autowired
protected SessionFactory sessionFactory;
protected final Logger logger = Logger.getLogger(this.getClass());
pl.com.radzikowski.webmail.service.MailManager
package pl.com.radzikowski.webmail.service;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@Component
@Transactional
public class MailManager extends AbstractManager
// some methods...
pl.com.radzikowski.webmail.HomeController
package pl.com.radzikowski.webmail.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import pl.com.radzikowski.webmail.service.MailManager;
@Controller
@RequestMapping("/")
public class HomeController
@Autowired
public MailManager mailManager;
@RequestMapping(value = "/", method = RequestMethod.GET)
public String homepage(ModelMap model)
return "homepage";
错误:
严重:加载应用程序时出现异常 严重:上下文 /WebMail 的取消部署失败 严重:加载应用程序时出现异常:java.lang.IllegalStateException:ContainerBase.addChild:开始:org.apache.catalina.LifecycleException:org.springframework.beans.factory.BeanCreationException:创建名为“homeController”的bean时出错:注入自动装配依赖失败;嵌套异常是 org.springframework.beans.factory.BeanCreationException:无法自动装配字段:public pl.com.radzikowski.webmail.service.MailManager pl.com.radzikowski.webmail.controller.HomeController.mailManager;嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [pl.com.radzikowski.webmail.service.MailManager] found for dependency: 预计至少有 1 个 bean 有资格作为此依赖项的自动装配候选者。依赖注解:@org.springframework.beans.factory.annotation.Autowired(required=true)
抱歉有很多代码,但我不知道是什么导致了这个错误。
已添加
我已经创建了界面:
@Component
public interface IMailManager
添加的工具:
@Component
@Transactional
public class MailManager extends AbstractManager implements IMailManager
并更改了自动连线:
@Autowired
public IMailManager mailManager;
但它仍然会引发错误(当我尝试使用 @Qualifier
时也是如此)
..无法自动装配字段:公共 pl.com.radzikowski.webmail.service.IMailManager pl.com.radzikowski.webmail.controller.HomeController.mailManager...
我也尝试过 @Component
和 @Transactional
的不同组合。
我不应该以某种方式在 web.xml 中包含 beans.xml 吗?
【问题讨论】:
你是如何加载 beans.xml 的? 现在只留下MailManagerInterface
和IMailManager
之一怎么样? :)
对不起,我错误地粘贴了代码。在我的程序中到处都有IMailManager
。
啊,正是.. 将<import resource="classpath:/beans.xml"/>
添加到mvc-dispatcher-servlet.xml
顺便问一下,你试过@emd 决定吗?
【参考方案1】:
您应该自动连接接口AbstractManager
而不是类MailManager
。如果你有不同的AbstractManager
实现,你可以写@Component("mailService")
然后@Autowired @Qualifier("mailService")
组合来自动装配特定的类。
这是因为 Spring 基于接口创建和使用代理对象。
【讨论】:
谢谢,但它仍然不起作用(同样的错误)。我在帖子中添加了更改。也许我没有在我的项目中正确包含/搜索某些内容? 我想知道是否有办法像@Autowired AbstractManager[] abstractManagers
这样包含所有实现。
@WoLfPwNeR 它应该完全按照你写的那样工作。见link
为什么不MailManager
?
我有两个 @Service
类实现相同的接口。两者都是另一个班级的@Autowired
。最初,当我使用特定的类类型时,它引起了与原始帖子相同的问题。按照这个答案,我改用不同@Qualifier("myServiceA")
和@Qualifier("myServiceB")
的接口类型,问题就解决了。谢谢!【参考方案2】:
我发生这种情况是因为我的测试与我的组件不在同一个包中。 (我已经重命名了我的组件包,但没有重命名我的测试包。)而且我在我的测试 @Configuration
类中使用了 @ComponentScan
,所以我的测试没有找到它们所依赖的组件。
因此,请仔细检查您是否收到此错误。
【讨论】:
这对我有用。当我重构代码以移动到新的包名称时,我的测试失败了,因为我在 @ComponentScan 中使用了旧的包名称。 如何在src/test
中使用src/main
中的@Configuration
类?【参考方案3】:
问题是应用程序上下文和 Web 应用程序上下文都在服务器启动期间注册在 WebApplicationContext 中。当您运行测试时,您必须明确告知要加载哪些上下文。
试试这个:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:/beans.xml", "/mvc-dispatcher-servlet.xml")
【讨论】:
如果正在使用 Spring Boot 怎么办? 我忘记了为 maven 依赖项配置组件扫描,并且每年都要为此苦苦挣扎。 如果您谈论的是应用程序本身而不是集成测试,对于 Spring boot,您可以这样做:@SpringBootApplication(scanBasePackages = "com.package.one", "com.package.two" )
【参考方案4】:
我花了很多时间在这上面!我的错!后来发现我声明注解Service
或Component
的类是abstract类型。已在 Springframework 上启用调试日志,但未收到任何提示。请检查类是否为抽象类型。如果这样,则应用的基本规则无法实例化抽象类。
【讨论】:
先生,你救了我的命,这很难被发现!【参考方案5】:我在从我的一个 jar 文件中自动连接类时遇到了同样的问题。 我通过使用 @Lazy 注释解决了这个问题:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
@Autowired
@Lazy
private IGalaxyCommand iGalaxyCommand;
【讨论】:
奇怪的是,我在从 Hibernate v4.3/Spring v4.3 迁移到 Hibernate v5.4/Spring v5.3 时需要这个...解决方案是添加这个@Lazy
,或启用org.springframework.data.repository
的调试日志?!?我猜是时间/比赛条件问题? (添加日志会使事情变慢以延迟解决问题的事情?)太奇怪了【参考方案6】:
这可能会对您有所帮助:
我的项目中有同样的例外。搜索后,我发现我在实现我想要@Autowired
的接口的类中缺少@Service
注释。
在您的代码中,您可以将@Service
注释添加到MailManager
类。
@Transactional
@Service
public class MailManager extends AbstractManager implements IMailManager
【讨论】:
@Service
注释包含@Component
。两者兼有是多余的。【参考方案7】:
您可以尝试使用@Component
仅注释您的具体实现吗?也许以下answer 可以提供帮助。这是一个类似的问题。我一般把Spring注解放在实现类中。
https://***.com/a/10322456/2619091
【讨论】:
【参考方案8】:按照 Max 的建议,正确的方法应该是自动装配 AbstractManager,但这也应该可以正常工作。
@Autowired
@Qualifier(value="mailService")
public MailManager mailManager;
和
@Component("mailService")
@Transactional
public class MailManager extends AbstractManager
【讨论】:
【参考方案9】:我最近遇到了这个问题,事实证明,我在我的服务类中导入了错误的注释。 Netbeans 有一个隐藏导入语句的选项,这就是为什么我有一段时间没有看到它。
我使用了@org.jvnet.hk2.annotations.Service
而不是@org.springframework.stereotype.Service
。
【讨论】:
【参考方案10】:在我的 Spring Boot 应用程序中遇到了同样的问题,即使我启用了特定于包的扫描,例如
@SpringBootApplication(scanBasePackages="com.*")
但是,通过在我的 Application 类中提供 @ComponentScan("com.*")
解决了这个问题。
【讨论】:
【参考方案11】: 上下文中可能不存在 BeanB 的一个原因 异常的另一个原因是存在两个 bean 或者上下文 bean 中未定义的定义是由 Spring 上下文中的名称请求的查看更多此网址:
http://www.baeldung.com/spring-nosuchbeandefinitionexception
【讨论】:
【参考方案12】: <context:component-scan base-package="com.*" />
同样的问题出现了,我通过保持注释完整并在调度程序 servlet :: 将基本包扫描保持为com.*.
来解决它,这对我有用。
【讨论】:
【参考方案13】:代替@Autowire MailManager mailManager,您可以模拟bean,如下所示:
import org.springframework.boot.test.mock.mockito.MockBean;
::
::
@MockBean MailManager mailManager;
另外,您可以在@SpringBootConfiguration
类中单独配置@MockBean MailManager mailManager;
并初始化如下:
@Autowire MailManager mailManager
【讨论】:
【参考方案14】:对我有用的解决方案是将所有相关类添加到测试类的 @ContextConfiguration
注释中。
要测试的类MyClass.java
有两个自动装配组件:AutowireA
和AutowireB
。这是我的解决方法。
@ContextConfiguration(classes = MyClass.class, AutowireA.class, AutowireB.class)
public class MyClassTest
...
【讨论】:
这是救命稻草,解决了我的问题。万一它对任何人都有帮助,我在 ControllerTest 类中遇到了同样的问题,没有找到 jackson ObjectMapper 依赖项,这是我自动装配的。上面使用 @ContextConfiguration 添加 ObjectMapper 的解决方案解决了我的问题。【参考方案15】:我猜是这里
<context:component-scan base-package="pl.com.radzikowski.webmail" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
所有注解首先被use-default-filters="false"
禁用,然后只有@Controller
启用注解。因此,您的 @Component
注释未启用。
【讨论】:
【参考方案16】:如果您正在测试您的控制器。 不要忘记在您的测试类上使用@WebAppConfiguration。
【讨论】:
【参考方案17】:发生这种情况是因为我向我的服务类添加了一个自动装配的依赖项,但忘记将它添加到我的服务单元测试中的注入模拟中。
单元测试异常似乎报告了服务类中的问题,而问题实际上是在单元测试中。回想起来,错误消息准确地告诉了我问题所在。
【讨论】:
【参考方案18】:我也遇到过同样的问题, 使用以下步骤解决了问题:
-
检查您正在自动布线的类/接口
对于接口业务逻辑,当它扩展接口方法时,我们应该使用
@service
。
对于作为数据库处理类的 Dao,我们应该使用 @Repository
。
→ 我们可以有效地使用@Service
、@Repository
和@Component
注解,并很快解决这个问题。
【讨论】:
【参考方案19】:如果您正在测试 DAO 层,您必须使用 @Autowire
注释,如下所示:
@Autowired
private FournisseurDao fournisseurDao;
不要在构造函数中注入存储库元素
【讨论】:
以上是关于@Autowired - 没有为依赖找到符合条件的 bean的主要内容,如果未能解决你的问题,请参考以下文章
Struts2 & Spring 错误:没有为依赖找到符合条件的 bean
没有为 @Autowired 服务找到依赖类型的限定 Bean
没有为 `MessagesApi` 找到符合条件的 bean
没有找到能够从类型 [java.lang.String] 转换为类型 [@Autowired @ManyToOne @JoinColumn com.papertrue.country.Country]