복붙노트

[SPRING] NoSuchBeanDefinitionException : 종속성에 대해 [저장소] 유형의 정규화 된 Bean이 없습니다. 적어도 하나의 자동 와이어로 간주되는 bean이 필요합니다.

SPRING

NoSuchBeanDefinitionException : 종속성에 대해 [저장소] 유형의 정규화 된 Bean이 없습니다. 적어도 하나의 자동 와이어로 간주되는 bean이 필요합니다.

비슷한 문제가 많은 웹 포털에서 설명되는 것으로 나타났습니다. 그러나 나는 이것이 유일한 상황이라고 생각한다. 봄 mvc 응용 프로그램에서 오류가 발생했습니다.

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'testController' defined in file [C:\Program Files (x86)\sts-bundle\pivotal-tc-server-developer-3.1.2.RELEASE\base-instance\wtpwebapps\ExpT1\WEB-INF\classes\com\expt\controller\TestController.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [com.expt.repositories.CategoryRepository]: No qualifying bean of type [com.expt.repositories.CategoryRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.expt.repositories.CategoryRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
    org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749)
    org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:185)

.....

org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.expt.repositories.CategoryRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
    org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1373)

코드는 아래와 같습니다. 충분한 코드가 복사 된 것 같습니다. 누락 된 부분과이 문제를 해결할 수있는 방법을 이해하는 데 도움을주십시오. 어떤 도움이 좋을까요 ... !! 암호: Appinitializer :

package com.expt.config;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;


public class AppInitialzer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        // TODO Auto-generated method stub
        return new Class[]{SpringAppContInit.class, SQLDevDataSource.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        // TODO Auto-generated method stub
        return new Class[]{WebMvcConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        // TODO Auto-generated method stub
        return new String[]{"/"};
    }

}

SQLDEVConfig :

package com.expt.config;

import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

@Configuration
@Profile("SQLDev")
@EnableJpaRepositories(basePackages={"com.expt.repositories"})
public class SQLDevDataSource extends AbstractJpaConfig {

    @Override
    public DataSource getDataSource() {
        // TODO Auto-generated method stub
        return createBasicDataSource("jdbc:jtds:sqlserver://LOCAL:1433/MYDB;", "net.sourceforge.jtds.jdbc.Driver", "UNMA", "PWD123");
    }
    public BasicDataSource createBasicDataSource(String jdbcUrl, String driverClass, String userName, String password) {
        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setUrl(jdbcUrl);
        dataSource.setDriverClassName(driverClass);
        dataSource.setUsername(userName);
        dataSource.setPassword(password);
        return dataSource;
    }

}

SpringAPpContInit :

package com.expt.config;

import org.springframework.context.ApplicationContextInitializer;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;

public class SpringAppContInit implements ApplicationContextInitializer<AnnotationConfigWebApplicationContext> {

    @Override
    public void initialize(AnnotationConfigWebApplicationContext applicationContext) {
        // TODO Auto-generated method stub
        ConfigurableEnvironment configEnv = applicationContext.getEnvironment();
        configEnv.addActiveProfile("SQLDev");
    }

}

AbstrackJpaConfig :

   package com.expt.config;

import java.util.HashMap;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.spi.PersistenceProvider;
import javax.sql.DataSource;

import org.hibernate.dialect.SQLServer2008Dialect;
import org.hibernate.jpa.HibernatePersistenceProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.orm.jpa.JpaDialect;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;

import com.expt.domain.Category;

public abstract class AbstractJpaConfig {

    public abstract DataSource getDataSource();

    @Bean(name="entityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource){
        Map<String, String> properties = new HashMap<String, String>();
        properties.put(org.hibernate.cfg.Environment.HBM2DDL_AUTO, "validate");
        properties.put(org.hibernate.cfg.Environment.DIALECT, SQLServer2008Dialect.class.getName());
        properties.put(org.hibernate.cfg.Environment.SHOW_SQL, "true");

        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(dataSource);
        //em.setPackagesToScan(Expense.class.getPackage().getName());
        em.setPackagesToScan(Category.class.getPackage().getName());
        //em.setPersistenceProvider(new HibernatePersistenceProvider());
        em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
        em.setJpaPropertyMap(properties);       
        return em;
    }

    @Bean(name = "transactionManager")
    public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }
}

제어 장치:

package com.expt.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.expt.domain.Category;
import com.expt.repositories.CategoryRepository;

@RestController
@RequestMapping("/test")
public class TestController {

    CategoryRepository catRepo;

    @Autowired
    public TestController(CategoryRepository catRepo) {
        this.catRepo = catRepo;
    }

    /*private CategoryService catSvc;

    @Autowired
    public TestController(CategoryService catSvc) {
        this.catSvc = catSvc;
    }*/

    @RequestMapping("/simple")
    public String test(){
        return "testing";
    }

    @RequestMapping("/json")
    public Iterable<Category> testJ(){
        return catRepo.findAll();
    }
}

카테고리 리포 지 토리 :

package com.expt.repositories;

import java.math.BigDecimal;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

import com.expt.domain.Category;

@Repository
public interface CategoryRepository extends JpaRepository<Category, BigDecimal> {

}

=========================================================

편집 : (거기에 덧글이 많이 추가 된 이러한 세부 정보를 추가 할 생각)

나는 https://github.com/scottfrederick/spring-music을 언급하고있다. 어떤 공용 클래스 AppInitializer를 사용 appinitializer에 대한 WebApplicationInitializer를 구현합니다.

전체 코드는 여기에 있습니다. 이전 프로젝트에서 사용한 코드입니다. 이것은 구성 클래스를 수동으로 등록하고 작동합니다. 그러나 AbstractAnnotationConfigDispatcherServletInitializer에서 확장 할 때 필요하지 않습니다.

   public class AppInitializer implements WebApplicationInitializer{

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        // TODO Auto-generated method stub
        configureAppContextInitializers(servletContext, SpringAppContInit.class.getName());

        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(RepositoryConfig.class);
        servletContext.addListener(new ContextLoaderListener(rootContext));

        AnnotationConfigWebApplicationContext webContext = new AnnotationConfigWebApplicationContext();
        webContext.register(WebMvcConfig.class);

        DispatcherServlet dispatcherServlet = new DispatcherServlet(webContext);
        ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher", dispatcherServlet);
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");
    }

    private void configureAppContextInitializers(ServletContext container, String... initClassNames) {
        String initializerClasses = container.getInitParameter(ContextLoader.CONTEXT_INITIALIZER_CLASSES_PARAM);

        String delimitedClassNames = StringUtils.arrayToDelimitedString(initClassNames, " ");

        if (StringUtils.hasText(initializerClasses)) {
            initializerClasses += " " + delimitedClassNames;
        }
        else {
            initializerClasses = delimitedClassNames;
        }

        container.setInitParameter(ContextLoader.CONTEXT_INITIALIZER_CLASSES_PARAM, initializerClasses);
    }
}

AbstractAnnotationConfigDispatcherServletInitializer의 경우 getRootConfigClasses 및 getServletConfigClasses 메소드는 암시 적으로 등록을 수행합니다. 이제 위의 코드가 작동하지 않는 이유를 찾고 있습니다. XML 또는 WebApplicationInitializer로 다시 되돌려 보냄으로써 해결할 수있는 해결 방법이 있습니다. 가능한 경우 API 문서 대신 업데이트 된 코드를 사용하여 해결책 및 이유를 찾고 있습니다. 튜토리얼이 필요해. API 문서는 문제 해결에 도움이되지 않습니다.

해결법

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

    1.WebApplicationInitializer의 독자적인 구현과 AbstractAnnotationConfigDispatcherServletInitializer를 확장 한 구현은 다릅니다. 사용자 정의 ApplicationContextInitializer를 등록하지 않아서 동작이 다릅니다. ApplicationContextInitializer를 등록하는 방법은 javadoc에서 설명합니다 (ApplicationContextInitializers의 컬렉션을 설정하는 두 가지 방법을 살펴보십시오).

    WebApplicationInitializer의 독자적인 구현과 AbstractAnnotationConfigDispatcherServletInitializer를 확장 한 구현은 다릅니다. 사용자 정의 ApplicationContextInitializer를 등록하지 않아서 동작이 다릅니다. ApplicationContextInitializer를 등록하는 방법은 javadoc에서 설명합니다 (ApplicationContextInitializers의 컬렉션을 설정하는 두 가지 방법을 살펴보십시오).

    public class AppInitialzer extends AbstractAnnotationConfigDispatcherServletInitializer {
    
        ...    
    
        protected ApplicationContextInitializer<?>[] getRootApplicationContextInitializers() {
            return new ApplicationContextInitializer[] { new SpringAppContInit() } ;
        }
    }
    

    그러나 ApplicationContextInitializer는 단순히 환경 또는 시스템 속성을 설정하여 이미 수행 할 수없는 작업을 실제로 추가하지 않습니다.

    spring.profiles.active=SQLDev
    

    그렇게하면 init이 필요하지 않습니다.

    나는 또한 강력하게 @EnableJpaRepositories가 잘못된 클래스에 있다고 믿는다. 사실 당신이 그 프로파일을 사용하고 싶다는 사실이 당신의 프로파일에 의존해서는 안된다는 것이다.

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

    2.이 주석을 사용하고 spring-data-jpa를 사용하는 경우 JpaRepository 대신 CrudRepository 또는 PagingAndSortingRepository를 확장합니다. TestController에서 autowired를 다음과 같이 지정합니다.

    이 주석을 사용하고 spring-data-jpa를 사용하는 경우 JpaRepository 대신 CrudRepository 또는 PagingAndSortingRepository를 확장합니다. TestController에서 autowired를 다음과 같이 지정합니다.

  3. from https://stackoverflow.com/questions/37498024/nosuchbeandefinitionexception-no-qualifying-bean-of-type-repository-found-for by cc-by-sa and MIT license