복붙노트

[SPRING] @Autowired - 종속성을 위해 발견 된 유형의 한정 콩

SPRING

@Autowired - 종속성을 위해 발견 된 유형의 한정 콩

Spring과 Hibernate를 사용하는 서비스에 대한 엔티티, 서비스 및 JUnit 테스트를 작성하여 프로젝트를 시작했습니다. 이 모든 것이 훌륭하게 작동합니다. 그런 다음 spring-mvc를 추가하여 여러 단계별 자습서를 사용하여이 웹 응용 프로그램을 만들었지 만 컨트롤러를 @Autowired 주석으로 만들려고 할 때 배포 중에 Glassfish에서 오류가 발생합니다. 나는 봄이 나의 서비스를 보지 못한다고 생각하지만, 많은 시도 후에도 나는 그것을 다룰 수 없다고 생각한다.

에 대한 서비스 테스트

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

@Autowired
public IMailManager mailManager;

하지만 여전히 오류가 발생합니다 (@Qualifier로 시도한 경우에도)

나는 @Component와 @Transactional의 다른 조합으로 시도했다.

어떻게해도 web.xml에 beans.xml을 포함하면 안됩니까?

해결법

  1. ==============================

    1.MailManager 클래스 대신 AbstractManager 인터페이스를 autowire해야합니다. AbstractManager의 구현이 다른 경우 @Component ( "mailService")를 작성한 다음 @Autowired @Qualifier ( "mailService") 조합을 사용하여 특정 클래스를 자동 작성합니다.

    MailManager 클래스 대신 AbstractManager 인터페이스를 autowire해야합니다. AbstractManager의 구현이 다른 경우 @Component ( "mailService")를 작성한 다음 @Autowired @Qualifier ( "mailService") 조합을 사용하여 특정 클래스를 자동 작성합니다.

    이는 Spring이 인터페이스를 기반으로 프록시 객체를 생성하고 사용한다는 사실 때문입니다.

  2. ==============================

    2.내 테스트가 내 구성 요소와 동일한 패키지에 없기 때문에 이런 일이 발생했습니다. (필자는 컴포넌트 패키지의 이름을 변경했지만 내 테스트 패키지는 변경하지 않았습니다.) 그리고 테스트 @Configuration 클래스에서 @ComponentScan을 사용했기 때문에 테스트에서 의존하는 컴포넌트를 찾지 못했습니다.

    내 테스트가 내 구성 요소와 동일한 패키지에 없기 때문에 이런 일이 발생했습니다. (필자는 컴포넌트 패키지의 이름을 변경했지만 내 테스트 패키지는 변경하지 않았습니다.) 그리고 테스트 @Configuration 클래스에서 @ComponentScan을 사용했기 때문에 테스트에서 의존하는 컴포넌트를 찾지 못했습니다.

    따라서이 오류가 발생하면 다시 확인하십시오.

  3. ==============================

    3.문제는 서버를 시작하는 동안 응용 프로그램 컨텍스트와 웹 응용 프로그램 컨텍스트가 모두 WebApplicationContext에 등록된다는 것입니다. 테스트를 실행할 때로드 할 컨텍스트를 명시 적으로 말해야합니다.

    문제는 서버를 시작하는 동안 응용 프로그램 컨텍스트와 웹 응용 프로그램 컨텍스트가 모두 WebApplicationContext에 등록된다는 것입니다. 테스트를 실행할 때로드 할 컨텍스트를 명시 적으로 말해야합니다.

    이 시도:

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

    4.이것으로 많은 시간을 보냈습니다! 내 잘못이야! 나중에 내가 주석 서비스 또는 컴포넌트를 선언 한 클래스가 추상 유형임을 알게되었습니다. Springframework에서 디버그 로그를 사용할 수 있었지만 힌트를받지 못했습니다. 클래스가 추상적 인 타입인지 확인하십시오. 그런 다음 기본 규칙이 적용되면 추상 클래스를 인스턴스화 할 수 없습니다.

    이것으로 많은 시간을 보냈습니다! 내 잘못이야! 나중에 내가 주석 서비스 또는 컴포넌트를 선언 한 클래스가 추상 유형임을 알게되었습니다. Springframework에서 디버그 로그를 사용할 수 있었지만 힌트를받지 못했습니다. 클래스가 추상적 인 타입인지 확인하십시오. 그런 다음 기본 규칙이 적용되면 추상 클래스를 인스턴스화 할 수 없습니다.

  5. ==============================

    5.@Component를 사용하여 구체적인 구현에만 주석을 달 수 있습니까? 아마도 다음과 같은 대답이 도움이 될 수 있습니다. 그것은 비슷한 종류의 문제입니다. 나는 보통 Spring 어노테이션을 구현 클래스에 넣는다.

    @Component를 사용하여 구체적인 구현에만 주석을 달 수 있습니까? 아마도 다음과 같은 대답이 도움이 될 수 있습니다. 그것은 비슷한 종류의 문제입니다. 나는 보통 Spring 어노테이션을 구현 클래스에 넣는다.

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

  6. ==============================

    6.정확한 방법은 Max가 제안한대로 AbstractManager를 autowire하는 것이지만 이것은 잘 작동 할 것이다.

    정확한 방법은 Max가 제안한대로 AbstractManager를 autowire하는 것이지만 이것은 잘 작동 할 것이다.

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

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

    7.나는 최근에이 문제에 휩쓸 렸고, 그것이 밝혀지면서 서비스 클래스에 잘못된 주석을 가져 왔습니다. Netbeans에는 가져 오기 명령문을 숨길 수있는 옵션이 있습니다. 그래서 나는 잠시 동안 그것을 보지 못했습니다.

    나는 최근에이 문제에 휩쓸 렸고, 그것이 밝혀지면서 서비스 클래스에 잘못된 주석을 가져 왔습니다. Netbeans에는 가져 오기 명령문을 숨길 수있는 옵션이 있습니다. 그래서 나는 잠시 동안 그것을 보지 못했습니다.

    @ org.springframework.stereotype.Service 대신 @ org.jvnet.hk2.annotations.Service를 사용했습니다.

  8. ==============================

    8.이 URL을 더 참조하십시오 :

    이 URL을 더 참조하십시오 :

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

  9. ==============================

    9.도움이 될 수 있습니다.

    도움이 될 수 있습니다.

    내 프로젝트에서 같은 예외가 있습니다. 내가 @Autowired하고 싶은 인터페이스를 구현하고있는 클래스에 @Service 어노테이션이 없다는 것을 알았을 때 검색 한 후.

    코드에서 MailManager 클래스에 @Service 주석을 추가 할 수 있습니다.

    @Transactional
    @Service
    public class MailManager extends AbstractManager implements IMailManager {
    
  10. ==============================

    10.내 추측은 여기에있다.

    내 추측은 여기에있다.

    <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 주석은 활성화되어 있지 않습니다.

  11. ==============================

    11.컨트롤러를 테스트하는 경우. 테스트 클래스에서 @WebAppConfiguration을 사용하는 것을 잊지 마십시오.

    컨트롤러를 테스트하는 경우. 테스트 클래스에서 @WebAppConfiguration을 사용하는 것을 잊지 마십시오.

  12. ==============================

    12.

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

    동일한 문제가 발생했습니다. 주석을 그대로 유지하고 발송자 서블릿 :: 기본 패키지를 com. *으로 스캔하여 해결했습니다. 이것은 나를 위해 일했다.

  13. ==============================

    13.내 서비스 클래스에 자동 종속성을 추가했으나 내 서비스 단위 테스트에서 주입 된 모의 객체에이를 추가하는 것을 잊어 버렸기 때문에 이런 일이 발생했습니다.

    내 서비스 클래스에 자동 종속성을 추가했으나 내 서비스 단위 테스트에서 주입 된 모의 객체에이를 추가하는 것을 잊어 버렸기 때문에 이런 일이 발생했습니다.

    단위 테스트 예외는 실제로 문제가 단위 테스트에있을 때 서비스 클래스의 문제를보고하는 것으로 나타났습니다. 돌이켜 보면, 오류 메시지는 문제가 무엇인지 정확히 알려줍니다.

  14. ==============================

    14.@Autowire MailManager mailManager 대신 다음과 같이 bean을 조롱 할 수 있습니다.

    @Autowire MailManager mailManager 대신 다음과 같이 bean을 조롱 할 수 있습니다.

    import org.springframework.boot.test.mock.mockito.MockBean;
    
    ::
    ::
    
    @MockBean MailManager mailManager;
    

    또한 @MockBean MailManager mailManager를 구성 할 수 있습니다. 별도로 @SpringBootConfiguration 클래스에 넣고 아래처럼 초기화하십시오 :

    @Autowire MailManager mailManager
    
  15. from https://stackoverflow.com/questions/20333147/autowired-no-qualifying-bean-of-type-found-for-dependency by cc-by-sa and MIT license