繁体   English   中英

@Autowired - 没有找到依赖类型的合格 bean

[英]@Autowired - No qualifying bean of type found for dependency

我通过使用 Spring 和 Hibernate 为服务创建实体、服务和 JUnit 测试来开始我的项目。所有这些都很好用。 然后我添加了 spring-mvc 以使用许多不同的分步教程制作这个 web 应用程序,但是当我尝试使用@Autowired注释制作 Controller 时,我在部署期间从 Glassfish 收到错误。 我猜是出于某种原因 Spring 没有看到我的服务,但经过多次尝试我仍然无法处理它。

测试服务

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:/beans.xml"})

@Autowired
MailManager mailManager;

正常工作。

也没有@Autowired的控制器,我可以在 web 浏览器中毫无问题地打开我的项目。

/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: Could not autowire field: public pl.com.radzikowski.webmail.service.MailManager pl.com.radzikowski.webmail.controller.HomeController.mailManager; 嵌套的异常是 org.springframework.beans.factory.NoSuchBeanDefinitionException:没有找到类型为 [pl.com.radzikowski.webmail.service.MailManager] 的符合条件的 bean 依赖项:预计至少有 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时也是如此)

..无法自动装配字段:public pl.com.radzikowski.webmail.service.IMailManager pl.com.radzikowski.webmail.controller.HomeController.mailManager...

我也尝试过@Component@Transactional的不同组合。

我不应该以某种方式在 web.xml 中包含 beans.xml 吗?

您应该自动装配接口AbstractManager而不是类MailManager 如果您有不同的AbstractManager实现,您可以编写@Component("mailService")@Autowired @Qualifier("mailService")组合来自动装配特定的类。

这是因为 Spring 基于接口创建和使用代理对象。

我发生这种情况是因为我的测试与我的组件不在同一个包中。 (我重命名了我的组件包,但没有重命名我的测试包。)而且我在我的测试@Configuration类中使用了@ComponentScan ,所以我的测试没有找到它们所依赖的组件。

因此,请仔细检查是否出现此错误。

问题是在服务器启动期间,应用程序上下文和 Web 应用程序上下文都在 WebApplicationContext 中注册。 当您运行测试时,您必须明确说明要加载哪些上下文。

试试这个:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:/beans.xml", "/mvc-dispatcher-servlet.xml"})

我花了很多时间在这上面! 我的坏! 后来发现我声明了注解Service或者Component的类是abstract类型的。 已在 Springframework 上启用调试日志,但未收到任何提示。 请检查该类是否为抽象类型。 如果那样的话,应用的基本规则就不能实例化一个抽象类。

这可能会帮助您:

我的项目中有同样的例外。 在搜索之后,我发现我在实现我想要@Autowired的接口的类中缺少@Service注释。

在您的代码中,您可以将@Service注释添加到MailManager类。

@Transactional
@Service
public class MailManager extends AbstractManager implements IMailManager {

从我的 jar 文件之一自动连接类时,我遇到了同样的问题。 我通过使用 @Lazy 注释解决了这个问题:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;

    @Autowired
    @Lazy
    private IGalaxyCommand iGalaxyCommand;

您可以尝试使用@Component仅注释您的具体实现吗? 也许以下答案会有所帮助。 这是一个类似的问题。 我通常将 Spring 注解放在实现类中。

https://stackoverflow.com/a/10322456/2619091

正确的方法应该是自动装配 AbstractManager,正如 Max 建议的那样,但这也应该可以正常工作。

@Autowired
@Qualifier(value="mailService")
public MailManager mailManager;

@Component("mailService")
@Transactional
public class MailManager extends AbstractManager {
}

我最近遇到了这个问题,结果证明我在我的服务类中导入了错误的注释。 Netbeans 有一个隐藏导入语句的选项,这就是为什么我有一段时间没有看到它。

我使用了@org.jvnet.hk2.annotations.Service而不是@org.springframework.stereotype.Service

即使我启用了特定于包的扫描,在我的 Spring Boot 应用程序中也遇到了同样的问题

@SpringBootApplication(scanBasePackages={"com.*"})

但是,通过在我的 Application 类中提供@ComponentScan({"com.*"})解决了这个问题。

  • BeanB 可能不存在于上下文中的原因之一
  • 导致异常的另一个原因是存在两个 bean
  • 或者未定义的上下文 bean 中的定义是通过 Spring 上下文中的名称请求的

查看更多这个网址:

http://www.baeldung.com/spring-nosuchbeandefinitionexception

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

同样的问题出现了,我通过保持注释完整并在调度程序 servlet 中解决了它::: 将基本包扫描保持为com.*. 这对我有用。

代替@Autowire MailManager mailManager,您可以模拟如下所示的bean:

import org.springframework.boot.test.mock.mockito.MockBean;

::
::

@MockBean MailManager mailManager;

另外,您可以配置@MockBean MailManager mailManager; 单独在@SpringBootConfiguration类中并初始化如下:

@Autowire MailManager mailManager

对我@ContextConfiguration的解决方案是将所有相关类添加到测试类的@ContextConfiguration注释中。

要测试的类MyClass.java有两个自动装配组件: AutowireAAutowireB 这是我的修复。

@ContextConfiguration(classes = {MyClass.class, AutowireA.class, AutowireB.class})
public class MyClassTest {
...
}

我的猜测是这里

<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注释未启用。

如果您正在测试您的控制器。 不要忘记在您的测试类上使用 @WebAppConfiguration。

我发生这种情况是因为我向我的服务类添加了一个自动装配的依赖项,但忘记将它添加到我的服务单元测试中注入的模拟中。

单元测试异常似乎在问题实际上在单元测试中时报告了服务类中的问题。 回想起来,错误消息准确地告诉了我问题出在哪里。

我遇到了同样的问题,使用以下步骤解决了问题:

  1. 检查您正在自动接线的类/接口
  2. 对于接口业务逻辑,我们应该在扩展接口方法时使用@service
  3. 对于作为数据库处理类的 Dao,我们应该使用@Repository

→ 我们可以有效地使用@Service@Repository@Component注解并且非常快速地解决这个问题。

如果您正在测试 DAO 层,您必须像这样使用@Autowire注释:

@Autowired
private FournisseurDao fournisseurDao;

不要在构造函数中注入存储库元素

我在多模块项目中重现了类似的问题, No qualifying bean of type例如:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.stockclient.repository.StockPriceRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}

这个错误的原因是在我的特定用例中缺少注释@EnableJpaRepositories

澄清一下:需要添加此注释以启用对Spring Data JPA的自动配置支持,以了解JPA存储库的路径。 默认情况下,它将仅扫描主应用程序 package 及其子包,以检测JPA存储库。

例如,有关更多详细信息,您可以参考这篇文章

当我在不同的@Configuration类中有两个标记为@Bean的同名方法时,这也发生在我身上。 似乎其中一个声明压倒了另一个。

正在配置非 SpringBoot、非 JPA、Hibernate 应用程序,并且在注入使用 @Repository 定义的 DAO @Repository实现时出现错误。

将声明从@Repository移至@Component有效。 请记住,您会失去此处提到的一些功能

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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