web-dev-qa-db-fra.com

@Autowired - Aucun bean qualifiant trouvé pour la dépendance

J'ai démarré mon projet en créant des entités, des services et des tests JUnit pour les services utilisant Spring et Hibernate. Tout cela fonctionne à merveille . Ensuite, j'ai ajouté spring-mvc pour créer cette application Web à l'aide de nombreux didacticiels pas à pas, mais lorsque j'essaie de créer Controller avec l'annotation @Autowired, je reçois erreurs de Glassfish lors du déploiement. Je suppose que, pour une raison quelconque, Spring ne voit pas mes services, mais après plusieurs tentatives, je ne peux toujours pas le gérer.

Tests de services avec 

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

et

@Autowired
MailManager mailManager;

fonctionne correctement.

Contrôleurs sans @Autowired aussi, je peux ouvrir mon projet dans un navigateur Web sans problème.

/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 <[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";
    }

}

Erreur:

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)}

Désolé pour beaucoup de code, mais je ne sais plus ce qui peut causer cette erreur.

Ajoutée

J'ai créé l'interface:

@Component
public interface IMailManager {

outils ajoutés:

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

et changé autowired:

@Autowired
public IMailManager mailManager;

Mais il y a toujours des erreurs (aussi quand j'ai essayé avec @Qualifier)

..Le champ ne peut pas être autowire: public pl.com.radzikowski.webmail.service.IMailManager pl.com.radzikowski.webmail.controller.HomeController.mailManager ...

J'ai également essayé différentes combinaisons de @Component et @Transactional.

Est-ce que je ne devrais pas inclure beans.xml dans web.xml?

65
Radzikowski

Vous devez utiliser autowire interface AbstractManager au lieu de la classe MailManager. Si vous avez différentes implémentations de AbstractManager, vous pouvez écrire la combinaison @Component("mailService") et ensuite @Autowired @Qualifier("mailService") pour classer automatiquement une classe.

Cela est dû au fait que Spring crée et utilise des objets proxy basés sur les interfaces.

58
Patison

Cela m'est arrivé parce que mes tests n'étaient pas dans le même package que mes composants. (J'avais renommé mon package de composants, mais pas mon package de test.) Et comme j'utilisais @ComponentScan dans ma classe de test @Configuration, mes tests ne trouvaient pas les composants sur lesquels ils s'appuyaient.

Donc, vérifiez que si vous obtenez cette erreur.

22
mooreds

Le fait est que le contexte d'application et le contexte d'application Web sont tous deux enregistrés dans WebApplicationContext lors du démarrage du serveur. Lorsque vous exécutez le test, vous devez indiquer explicitement les contextes à charger. 

Essaye ça:

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

J'ai passé beaucoup de temps avec ça! Ma faute! Plus tard, j'ai découvert que la classe sur laquelle j'avais déclaré l'annotation Service ou Component était de type abstract Avait activé les journaux de débogage sur Springframework mais aucun indice n’avait été reçu. Veuillez vérifier si la classe est de type abstrait. Si alors, la règle de base appliquée, ne peut pas instancier une classe abstraite.

5
James Jithin

La manière correcte doit être de signer automatiquement AbstractManager, comme le suggère Max, mais cela devrait également fonctionner correctement.

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

et

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

Pouvez-vous essayer d'annoter uniquement votre implémentation concrète avec @Component? Peut-être que la réponse suivante answer pourrait vous aider. C'est un peu un problème similaire. Je mets généralement des annotations Spring dans les classes d'implémentation.

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

3
whyem

J'ai récemment rencontré ce problème et, en fin de compte, j'ai importé la mauvaise annotation dans ma classe de service. Netbeans a une option pour masquer les instructions d'importation, c'est pourquoi je ne l'ai pas vue depuis un certain temps.

J'ai utilisé @org.jvnet.hk2.annotations.Service au lieu de @org.springframework.stereotype.Service.

2
kazmer

Cela peut vous aider:

J'ai la même exception dans mon projet. Après avoir cherché et constaté que l'annotation @Service de la classe où je suis en train d'implémenter l'interface que je souhaite @Autowired manquait.

Dans votre code, vous pouvez ajouter l'annotation @Service à la classe MailManager.

@Transactional
@Service
public class MailManager extends AbstractManager implements IMailManager {
1
Akshay Pethani
  • Une raison pour laquelle BeanB peut ne pas exister dans le contexte 
  • L'existence de deux haricots constitue une autre cause d'exception.
  • Ou des définitions dans le bean contexte qui n'est pas défini sont demandées par nom à partir du contexte Spring

voir plus cette url:

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

1
zohreh

Je suppose que c'est ici

<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>

toutes les annotations sont d'abord désactivées par use-default-filters = "false", puis uniquement l'annotation @Controller activée. Ainsi, votre annotation @Component n'est pas activée.

0
LoBo

Au lieu de @Autowire MailManager mailManager, vous pouvez simuler le bean comme indiqué ci-dessous:

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

::
::

@MockBean MailManager mailManager;

De plus, vous pouvez configurer @MockBean MailManager mailManager; séparément dans la classe @SpringBootConfiguration et l'initialiser comme ci-dessous:

@Autowire MailManager mailManager
0
Barani r

Je faisais face au même problème lors du câblage automatique de la classe à partir de l'un de mes fichiers jar ..__ J'ai résolu le problème en utilisant l'annotation @Lazy:

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

    @Autowired
    @Lazy
    private IGalaxyCommand iGalaxyCommand;

0
Ved Singh

Si vous testez votre contrôleur… .. N'oubliez pas d'utiliser @WebAppConfiguration sur votre classe de test.

0
Joao Luiz Cadore

Cela est dû au fait que j'ai ajouté une dépendance auto-câblée à ma classe de service, mais que j'ai oublié de l'ajouter aux simulacres injectés dans mon test d'unité de service.

L'exception de test unitaire semblait signaler un problème dans la classe de service alors qu'il était en réalité dans le test unitaire. Rétrospectivement, le message d'erreur m'a dit exactement quel était le problème.

0
Curtis Yallop

J'ai rencontré le même problème dans mon application de démarrage printanier même si les analyses spécifiques à mon paquetage étaient activées comme

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

Mais le problème a été résolu en fournissant @ComponentScan({"com.*"}) dans ma classe d'application.

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

le même problème est arrivé, je l'ai résolu en gardant les annotations intactes et dans dispatcher servlet :: en conservant l'analyse du paquet de base comme com.*., cela a fonctionné pour moi. 

0
Ramanpreet Singh