Подтвердить что ты не робот

@Autowired - нет квалификационного bean типа, найденного для зависимости

Я начал свой проект, создав сущности, службы и тесты JUnit для служб, использующих Spring и Hibernate. Все это отлично работает. Затем я добавил spring -mvc, чтобы сделать это веб-приложение, используя много разных пошаговых руководств, но когда я пытаюсь сделать Controller с @Autowired аннотацией, я получаю ошибки от Glassfish во время развертывания. Я думаю, что по какой-то причине Spring не видит мои услуги, но после многих попыток я все еще не могу справиться с этим.

Тесты для служб с

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

и

@Autowired
MailManager mailManager;

работает правильно.

Контроллеры без @Autowired тоже, я могу без проблем открыть свой проект в веб-браузере.

/SRC/основные/ресурсы/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 <[email protected]>
 */
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";
    }

}

Ошибка:

SEVERE:   Exception while loading the app
SEVERE:   Undeployment failed for context /WebMail
SEVERE:   Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'homeController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: public pl.com.radzikowski.webmail.service.MailManager pl.com.radzikowski.webmail.controller.HomeController.mailManager; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [pl.com.radzikowski.webmail.service.MailManager] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@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) ​​

.. Не удалось создать поле autwire: public pl.com.radzikowski.webmail.service.IMailManager pl.com.radzikowski.webmail.controller.HomeController.mailManager...

Я пробовал с различными комбинациями @Component и @Transactional тоже.

Не следует ли включать beans.xml в web.xml?

4b9b3361

Ответ 1

Вы должны использовать autwire интерфейс AbstractManager вместо класса MailManager. Если у вас разные реализации AbstractManager, вы можете написать комбинацию @Component("mailService") и затем @Autowired @Qualifier("mailService") для автоподготовки определенного класса.

Это связано с тем, что Spring создает и использует прокси-объекты на основе интерфейсов.

Ответ 2

У меня это произошло, потому что мои тесты не были в том же пакете, что и мои компоненты. (Я переименовал свой компонентный пакет, но не мой тестовый пакет.) И я использовал @ComponentScan в своем тестовом классе @Configuration, поэтому мои тесты не нашли компоненты, на которые они ссылались.

Итак, дважды проверьте, если вы получите эту ошибку.

Ответ 3

Дело в том, что и контекст приложения, и контекст веб-приложения регистрируются в WebApplicationContext во время запуска сервера. Когда вы запускаете тест, вы должны явно указать, какие контексты загружать.

Попробуйте следующее:

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

Ответ 4

Провел большую часть своего времени с этим! Виноват! Позже выяснилось, что класс, на котором я объявил аннотацию Service или Component, был абстрактным по типу. Включили журналы отладки в Springframework, но никакой подсказки не было получено. Проверьте, есть ли класс абстрактного типа. Если тогда применяемое основное правило не может создать абстрактный класс.

Ответ 5

Правильный путь должен состоять в том, чтобы автообновить AbstractManager, как предложил Макс, но это также должно работать нормально.

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

и

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

Ответ 6

Можете ли вы попытаться аннотировать только вашу конкретную реализацию с помощью @Component? Возможно, следующий ответ мог бы помочь. Это своего рода аналогичная проблема. Обычно я добавляю аннотации Spring в классы реализации.

fooobar.com/questions/103013/...

Ответ 7

В последнее время я столкнулся с этим, и, как оказалось, я импортировал неправильную аннотацию в свой класс сервиса. Netbeans имеет возможность скрывать инструкции импорта, поэтому я не видел его в течение некоторого времени.

Я использовал @org.jvnet.hk2.annotations.Service вместо @org.springframework.stereotype.Service.

Ответ 8

Это может помочь вам:

У меня такое же исключение в моем проекте. После поиска я обнаружил, что мне не хватает аннотации @Service в классе, где я реализую интерфейс, который я хочу для @Autowired.

В своем коде вы можете добавить аннотацию @Service к классу MailManager.

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

Ответ 9

  • Одна из причин, по которой BeanB может не существовать в контексте
  • Еще одной причиной для исключения является наличие двух бобов
  • Или определения в компоненте bean, которые не определены, запрашиваются по имени из контекста Spring.

увидеть больше этот URL:

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

Ответ 10

Я столкнулся с той же проблемой при автоматическом подключении класса к одному из файлов JAR. Я исправил проблему с помощью аннотации @Lazy:

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

    @Autowired
    @Lazy
    private IGalaxyCommand iGalaxyCommand;

Ответ 11

Я предполагаю, что здесь

<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 не включена.

Ответ 12

Если вы тестируете свой контроллер. Не забудьте использовать @WebAppConfiguration в тестовом классе.

Ответ 13

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

Пришла та же проблема, я решил ее, сохранив аннотации в целости и в сервлете диспетчера :: сохраняя сканирование базового пакета как com.*. это сработало для меня.

Ответ 14

Это произошло из-за того, что я добавил в свой класс обслуживания автоматическую зависимость, но забыл добавить ее к внедренным макетам в своем тесте модуля обслуживания.

Исключение модульного теста, по-видимому, сообщает о проблеме в классе обслуживания, когда проблема была на самом деле в модульном тесте. В ретроспективе, сообщение об ошибке сообщило мне, в чем именно заключалась проблема.

Ответ 15

Вместо @Autowire MailManager mailManager вы можете смоделировать bean-компонент, как указано ниже:

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

::
::

@MockBean MailManager mailManager;

Также вы можете настроить @MockBean MailManager mailManager; отдельно в классе @SpringBootConfiguration и инициализируйте, как @SpringBootConfiguration ниже:

@Autowire MailManager mailManager

Ответ 16

Столкнулся с той же проблемой в моем весеннем загрузочном приложении, хотя у меня было включено сканирование для конкретного пакета, например

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

Но проблема была решена путем предоставления @ComponentScan({"com.*"}) В моем классе приложения.