it-swarm.com.de

@Autowired - Es wurde keine qualifizierende Bean des Typs für die Abhängigkeit gefunden

Ich habe mein Projekt damit begonnen, Entitäten, Services und JUnit-Tests für Services mit Spring und Hibernate zu erstellen. All das funktioniert prima ..__ Dann habe ich spring-mvc hinzugefügt, um diese Webanwendung mit vielen verschiedenen Schritt-für-Schritt-Tutorials zu machen, aber wenn ich versuche, Controller mit @Autowired-Annotation zu erstellen, bekomme ich es Fehler von Glassfish während der Bereitstellung. Ich schätze, dass Spring meine Dienstleistungen aus irgendeinem Grund nicht sieht, aber nach vielen Versuchen kann ich immer noch nicht damit umgehen.

Tests für Dienste mit 

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

und

@Autowired
MailManager mailManager;

funktioniert einwandfrei.

Controller ohne @Autowired, ich kann mein Projekt problemlos im Webbrowser öffnen.

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

}

Error:

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

Entschuldigung für eine Menge Code, aber ich weiß nicht mehr, was diesen Fehler verursachen kann.

Hinzugefügt

Ich habe die Schnittstelle erstellt:

@Component
public interface IMailManager {

hinzugefügte Geräte:

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

und geändert autowired:

@Autowired
public IMailManager mailManager;

Es wirft aber trotzdem Fehler (auch wenn ich es mit @Qualifier probiert habe)

..Das Feld konnte nicht automatisch geschlossen werden: public pl.com.radzikowski.webmail.service.IMailManager pl.com.radzikowski.webmail.controller.HomeController.mailManager ...

Ich habe es auch mit verschiedenen Kombinationen von @Component und @Transactional versucht.

Soll ich beans.xml nicht irgendwie in web.xml einfügen?

65
Radzikowski

Sie sollten die Schnittstelle AbstractManager anstelle der Klasse MailManager verwenden. Wenn Sie verschiedene Implemetationen von AbstractManager haben, können Sie @Component("mailService") und dann @Autowired @Qualifier("mailService") zur autowire-spezifischen Klasse schreiben.

Dies liegt daran, dass Spring Proxy-Objekte auf Basis der Schnittstellen erstellt und verwendet.

58
Patison

Ich hatte das passiert, weil meine Tests nicht im selben Paket waren wie meine Komponenten. (Ich hatte mein Komponentenpaket umbenannt, aber nicht mein Testpaket.) Und ich verwendete @ComponentScan in meiner Test @Configuration-Klasse, sodass meine Tests nicht die Komponenten fanden, auf die sie sich verlassen hatten.

Überprüfen Sie dies also, wenn Sie diesen Fehler erhalten.

22
mooreds

Die Sache ist, dass sowohl der Anwendungskontext als auch der Webanwendungskontext während des Serverstarts im WebApplicationContext registriert werden. Wenn Sie den Test ausführen, müssen Sie explizit angeben, welche Kontexte geladen werden sollen. 

Versuche dies:

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

Verbrachte viel Zeit damit! Mein Fehler! Später fand ich heraus, dass die Klasse, für die ich die Anmerkung Service oder Component deklarierte, vom Typ abstract war. Hatte Debug-Protokolle in Springframework aktiviert, es wurde jedoch kein Hinweis empfangen. Bitte überprüfen Sie, ob die Klasse einen abstrakten Typ hat. Wenn die Basisregel dann angewendet wird, kann keine abstrakte Klasse instanziiert werden.

5
James Jithin

Der richtige Weg sollte sein, AbstractManager automatisch zu verwenden, wie Max vorgeschlagen hatte, aber dies sollte auch gut funktionieren.

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

und

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

Können Sie versuchen, nur Ihre konkrete Implementierung mit @Component zu kommentieren? Vielleicht könnte die folgende Antwort helfen. Es ist ein ähnliches Problem. Normalerweise füge ich Spring-Anmerkungen in die Implementierungsklassen ein.

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

3
whyem

Ich bin kürzlich dazu gekommen, und wie sich herausstellte, habe ich die falsche Anmerkung in meine Serviceklasse importiert. Netbeans hat eine Option zum Ausblenden von Importanweisungen, deshalb habe ich es einige Zeit nicht gesehen.

Ich habe @org.jvnet.hk2.annotations.Service anstelle von @org.springframework.stereotype.Service verwendet.

2
kazmer

Dies kann Ihnen helfen:

Ich habe die gleiche Ausnahme in meinem Projekt. Nach dem Suchen habe ich festgestellt, dass mir die @Service-Annotation der Klasse fehlt, in der ich die Schnittstelle implementiere, die ich @Autowired möchte.

In Ihrem Code können Sie die @Service-Annotation zur MailManager-Klasse hinzufügen.

@Transactional
@Service
public class MailManager extends AbstractManager implements IMailManager {
1
Akshay Pethani
  • Ein Grund, warum BeanB möglicherweise nicht im Kontext vorhanden ist 
  • Eine weitere Ursache für die Ausnahme ist das Vorhandensein von zwei Bohnen
  • Oder Definitionen in der nicht definierten Context-Bean werden über den Namen aus dem Spring-Kontext angefordert

sehen Sie mehr diese URL:

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

1
zohreh

Meine Vermutung ist das hier

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

alle Anmerkungen werden zuerst mit use-default-filters = "false" deaktiviert und dann nur die @Controller-Anmerkung aktiviert. Ihre @Component-Annotation ist daher nicht aktiviert.

0
LoBo

Anstelle von @Autowire MailManager mailManager können Sie die Bean wie folgt simulieren:

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

::
::

@MockBean MailManager mailManager;

Sie können @MockBean MailManager mailManager; auch separat in der @SpringBootConfiguration-Klasse konfigurieren und wie folgt initialisieren:

@Autowire MailManager mailManager
0
Barani r

Ich war mit demselben Problem konfrontiert, als ich die Klasse automatisch von einer meiner Jar-Datei verdrahtete ... Ich habe das Problem mit der @Lazy-Anmerkung behoben:

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

    @Autowired
    @Lazy
    private IGalaxyCommand iGalaxyCommand;

0
Ved Singh

Wenn Sie Ihren Controller testen, vergessen Sie nicht @WebAppConfiguration für Ihre Testklasse zu verwenden.

0

Ich hatte das passiert, weil ich meiner Serviceklasse eine automatisch abhängige Abhängigkeit hinzugefügt habe, die ich jedoch vergessen habe, sie zu den injizierten Mocks in meinem Service Unit-Test hinzuzufügen.

Die Einheitentestausnahme schien ein Problem in der Serviceklasse zu melden, als das Problem tatsächlich im Komponententest war. Im Nachhinein sagte mir die Fehlermeldung genau, was das Problem war.

0
Curtis Yallop

In meiner Spring Boot-Anwendung trat das gleiche Problem auf, obwohl ich meine paketspezifischen Scans wie aktiviert hatte

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

Das Problem wurde jedoch behoben, indem in meiner Anwendungsklasse @ComponentScan({"com.*"}) angegeben wurde.

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

dieselbe Ausgabe erschien, ich löste es, indem ich die Anmerkungen intakt hielt und im Dispatcher servlet :: den Basispaketscan als com.*. behielt, was für mich funktionierte. 

0