@Autowired - निर्भरता के लिए पाया गया प्रकार का कोई योग्य बीन नहीं है


89

मैंने स्प्रिंग और हाइबरनेट का उपयोग करके सेवाओं के लिए इकाइयाँ, सेवाएँ और JUnit परीक्षण बनाकर अपनी परियोजना शुरू की है। यह सब बहुत अच्छा काम करता है। तब मैंने कई अलग-अलग चरण-दर-चरण ट्यूटोरियल का उपयोग करके इस वेब एप्लिकेशन को बनाने के लिए स्प्रिंग-एमवीसी को जोड़ा है, लेकिन जब मैं @Autowired एनोटेशन के साथ नियंत्रक बनाने की कोशिश कर रहा हूं, तो मुझे तैनाती के दौरान ग्लासफिश से त्रुटियां मिल रही हैं। मुझे लगता है कि किसी कारण से स्प्रिंग मेरी सेवाओं को नहीं देखती है, लेकिन कई प्रयासों के बाद भी मैं इसे संभाल नहीं पा रहा हूं।

के साथ सेवाओं के लिए टेस्ट

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

}

त्रुटि:

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 के साथ प्रयास किया है)

..कॉ नहीं ऑटोवेयर फ़ील्ड: सार्वजनिक pl.com.radzikowski.webmail.service.IMailManager pl.com.radzikowski.webmail.controller.omeController.mailManager ...

मैंने @Component और @Transactional के विभिन्न संयोजनों के साथ भी प्रयास किया है।

क्या मुझे web.xml में सेम.एक्सएमएल को किसी तरह शामिल नहीं करना चाहिए?


आप सेम को कैसे लोड कर रहे हैं। xml
माइकल वाइल्स

अब कैसे के बारे में केवल एक MailManagerInterfaceऔर छोड़ने के लिए IMailManager? :)
२१:१३ बजे

क्षमा करें, मैंने कोड को बुरी तरह चिपकाया है। मेरे कार्यक्रम में IMailManagerहर जगह है।
राडज़िकोव्स्की

आह, वास्तव में .. जोड़ने <import resource="classpath:/beans.xml"/>के लिएmvc-dispatcher-servlet.xml
Patison

वैसे, क्या आपने @emd निर्णय लेने की कोशिश की?
पाटिसन

जवाबों:


81

आपको AbstractManagerक्लास के बजाय इंटरफ़ेस को ऑटो करना चाहिए MailManager। यदि आपके पास अलग-अलग गुणनखंड हैं, तो AbstractManagerआप लिख सकते हैं @Component("mailService")और फिर @Autowired @Qualifier("mailService")ऑटॉयर विशिष्ट वर्ग के साथ संयोजन कर सकते हैं ।

यह इस तथ्य के कारण है कि स्प्रिंग इंटरफेस के आधार पर प्रॉक्सी ऑब्जेक्ट बनाता है और उपयोग करता है।


2
धन्यवाद, लेकिन यह अभी भी काम नहीं करता है (एक ही त्रुटि)। मैंने पोस्ट में बदलाव जोड़े। शायद मैं अपने प्रोजेक्ट में कुछ ठीक से शामिल / खोज नहीं करता / करती हूं?
रदिज़कोव्स्की

मैं सोच रहा था कि क्या ऐसा कुछ करने का एक तरीका @Autowired AbstractManager[] abstractManagersहै जिसमें इसके सभी कार्यान्वयन शामिल हैं।
WoLfPwNeR

@WoLfPwNeR जैसा आपने लिखा है वैसा ही काम करना चाहिए लिंक
Patison

क्यों नहीं MailManager?
एलेक्स78191

मेरे पास @Serviceएक ही इंटरफ़ेस लागू करने वाली दो कक्षाएं हैं। दोनों @Autowiredदूसरी कक्षा में हैं। प्रारंभ में यह मूल पद के समान समस्या का कारण बना जब मैंने विशिष्ट वर्ग प्रकार का उपयोग किया। इस जवाब के बाद, मैं अलग से इंटरफ़ेस प्रकार का उपयोग करने के लिए बदल @Qualifier("myServiceA")और @Qualifier("myServiceB"), और समस्या का समाधान किया गया था। धन्यवाद!
जियालिन

27

मैंने ऐसा इसलिए किया क्योंकि मेरे परीक्षण मेरे घटकों के समान पैकेज में नहीं थे। (मैंने अपने घटक पैकेज का नाम बदल लिया था, लेकिन मेरे परीक्षण पैकेज का नहीं।) और मैं @ComponentScanअपने परीक्षण @Configurationवर्ग में उपयोग कर रहा था , इसलिए मेरे परीक्षणों में वे घटक नहीं मिल रहे थे, जिन पर वे निर्भर थे।

इसलिए, यह जांचें कि यदि आपको यह त्रुटि मिलती है।


2
इसने मेरे लिए काम किया। जब मैंने एक नए पैकेज के नाम पर जाने के लिए कोड को वापस ले लिया तो मेरे परीक्षण विफल हो गए क्योंकि मैं @ComponentScan में पुराने पैकेज के नाम का उपयोग कर रहा था।
विजय वेपकोमा जूला

1
कैसे उपयोग करने के लिए @Configurationसे वर्ग src/mainमें src/test?
एलेक्स78191

10

बात यह है कि सर्वर स्टार्टअप के दौरान अनुप्रयोग संदर्भ और वेब अनुप्रयोग संदर्भ दोनों WebApplicationContext में पंजीकृत हैं। जब आप परीक्षण चलाते हैं तो आपको स्पष्ट रूप से बताना होगा कि कौन सा संदर्भ लोड करना है।

इसे इस्तेमाल करे:

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

1
स्प्रिंग बूट का उपयोग करने पर यह कैसे करना है?
एलेक्स78191

मैं मावेन निर्भरता के लिए घटक स्कैन को कॉन्फ़िगर करने और वर्ष में एक बार इस तरह से संघर्ष करने के बारे में भूल जाता हूं।
b15

यदि आप आवेदन के बारे में बात कर रहे हैं और एकीकरण परीक्षण नहीं करते हैं, तो स्प्रिंग बूट के लिए आप इसे इस तरह से कर सकते हैं: @SpringBootApplication(scanBasePackages = { "com.package.one", "com.package.two" })
b15

5

इस के साथ मेरा बहुत समय बिताया! मेरी गलती! बाद में पाया कि जिस वर्ग पर मैंने एनोटेशन घोषित किया था Serviceया Componentवह टाइप एब्सट्रैक्ट का था। स्प्रिंगफ्रेमवर्क पर डिबग लॉग को सक्षम किया था लेकिन कोई संकेत नहीं मिला था। कृपया जाँचें कि क्या वर्ग अमूर्त प्रकार का है। यदि तब, मूल नियम लागू होता है, तो एक अमूर्त वर्ग को तत्काल नहीं किया जा सकता है।


1
आपने मेरा दिन बचाया, यह पता लगाने के लिए बहुत मुश्किल है!
जफेट ओन्गेरी - इंकलामेवा ११'१

3

क्या आप केवल अपने ठोस कार्यान्वयन की व्याख्या करने का प्रयास कर सकते हैं @Component? शायद निम्नलिखित उत्तर मदद कर सकता है। यह एक समान समस्या है। मैं आमतौर पर स्प्रिंग एनोटेशन को कार्यान्वयन कक्षाओं में रखता हूं।

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


3

मैं उसी मुद्दे का सामना कर रहा था जब मेरी एक जार फ़ाइल से क्लास को ऑटो-वायर कर रहा था। मैंने @Lazy एनोटेशन का उपयोग करके समस्या को ठीक किया:

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

    @Autowired
    @Lazy
    private IGalaxyCommand iGalaxyCommand;


2

जैसा कि मैक्स ने सुझाव दिया था, एब्सट्रैक्ट मैनजेर को सही करने के लिए सही तरीका होगा, लेकिन यह ठीक भी काम करना चाहिए।

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

तथा

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

2

मैं हाल ही में इसमें भाग गया, और जैसा कि यह निकला, मैंने अपनी सेवा वर्ग में गलत एनोटेशन आयात किया है। Netbeans में आयात विवरण छिपाने का विकल्प होता है, इसलिए मैंने इसे कुछ समय के लिए नहीं देखा।

के @org.jvnet.hk2.annotations.Serviceबजाय मैंने उपयोग किया है @org.springframework.stereotype.Service


1
  • एक कारण बीएनबी संदर्भ में मौजूद नहीं हो सकता है
  • अपवाद का एक अन्य कारण दो बीन का अस्तित्व है
  • या संदर्भ बीन में परिभाषाएँ जो परिभाषित नहीं की गई हैं, वसंत संदर्भ से नाम से अनुरोध किया गया है

और देखें यह url:

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


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

एक ही मुद्दा आ गया है, मैंने एनोटेशन को बरकरार रखते हुए और डिस्पैचर सर्वलेट में इसे हल किया है :: बेस पैकेज को स्कैन करके रखना क्योंकि com.*.यह मेरे लिए काम करता है।


1

यह आपकी मदद कर सकता है:

मेरे प्रोजेक्ट में मेरे पास एक ही अपवाद है। खोज करने के बाद मैंने पाया कि मैं उस कक्षा में @Service एनोटेशन को याद कर रहा हूं जहां मैं उस इंटरफ़ेस को लागू कर रहा हूं जो मैं @Autowired को चाहता हूं।

अपने कोड में आप MailManager वर्ग में @Service एनोटेशन जोड़ सकते हैं।

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

@Serviceएनोटेशन शामिल @Component। दोनों का होना बेमानी है।
एंथनीडब्ल्यू

1

@Autowire MailManager mailManager के बजाय, आप नीचे दिए अनुसार बीन का मज़ाक उड़ा सकते हैं:

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

::
::

@MockBean MailManager mailManager;

इसके अलावा, आप क्लास @MockBean MailManager mailManager;में अलग से कॉन्फ़िगर कर सकते हैं @SpringBootConfigurationऔर नीचे की तरह इनिशियलाइज़ कर सकते हैं:

@Autowire MailManager mailManager

1

मेरे स्प्रिंग बूट एप्लिकेशन में भी यही समस्या आई, जबकि मेरे पास मेरे पैकेज विशिष्ट स्कैन जैसे सक्षम थे

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

लेकिन, @ComponentScan({"com.*"})मेरे आवेदन वर्ग में प्रदान करके समस्या का समाधान किया गया था ।


0

मेरा अनुमान है कि यहाँ है

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

सभी एनोटेशन पहले उपयोग-डिफ़ॉल्ट-फ़िल्टर = "गलत" द्वारा अक्षम किए जाते हैं और फिर केवल @ कंट्रोलर एनोटेशन सक्षम किया जाता है। इस प्रकार, आपका @Component एनोटेशन सक्षम नहीं है।


0

यदि आप अपने नियंत्रक का परीक्षण कर रहे हैं। अपने परीक्षण वर्ग पर @WebAppConfiguration का उपयोग करना न भूलें।


0

मेरे साथ ऐसा हुआ था क्योंकि मैंने अपनी सेवा श्रेणी में एक स्वत: निर्भरता जोड़ दी थी, लेकिन अपनी सेवा इकाई परीक्षण में इसे इंजेक्शन के साथ जोड़ना भूल गया।

यूनिट टेस्ट अपवाद समस्या की रिपोर्ट करने के लिए सेवा वर्ग में समस्या तब दिखाई दी जब समस्या वास्तव में यूनिट टेस्ट में थी। पूर्वव्यापीकरण में, त्रुटि संदेश ने मुझे बताया कि समस्या क्या थी।


0

मेरे लिए काम करने वाला समाधान सभी प्रासंगिक वर्गों को @ContextConfigurationपरीक्षण वर्ग के लिए एनोटेशन में जोड़ना था ।

परीक्षण करने के लिए वर्ग MyClass.java, में दो ऑटोवार्ड घटक थे: AutowireAऔर AutowireB। यहाँ मेरा फिक्स है।

@ContextConfiguration(classes = {MyClass.class, AutowireA.class, AutowireB.class})
public class MyClassTest {
...
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.