簡體   English   中英

NoSuchBeanDefinitionException: 沒有為依賴找到 [Repository] ​​類型的合格 bean:預計至少有 1 個符合自動裝配條件的 bean

[英]NoSuchBeanDefinitionException: No qualifying bean of type [Repository] found for dependency: expected at least 1 bean which qualifies as autowire

我發現類似的問題解釋了許多門戶網站。 但我想這是獨特的情況。 我在 spring 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)

代碼如下。 我認為已經復制了足夠多的代碼。 請幫助我了解缺少什么以及如何解決此問題。 任何幫助都會很棒......! 代碼: 應用初始化程序:

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

}

SQLDEV 配置:

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 它使用public class AppInitializer implements WebApplicationInitializer為 appinitializer public class AppInitializer implements 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情況下,方法getRootConfigClassesgetServletConfigClasses隱式地進行注冊。現在我正在尋找我上面的代碼不起作用的原因。 我有解決方法,比如我可以通過恢復到 XMLs 或WebApplicationInitializer使其工作。 如果可能,我正在尋找更新代碼而不是 API 文檔的解決方案和原因。 我需要一個教程。 API 文檔不會幫助我解決問題。

您自己的WebApplicationInitializer實現和擴展AbstractAnnotationConfigDispatcherServletInitializer的實現是不同的。 它們的行為不同,這是因為您沒有注冊自定義ApplicationContextInitializer javadoc 中解釋了如何注冊ApplicationContextInitializer (注意設置ApplicationContextInitializer集合的兩種方法。)。

public class AppInitialzer extends AbstractAnnotationConfigDispatcherServletInitializer {

    ...    

    protected ApplicationContextInitializer<?>[] getRootApplicationContextInitializers() {
        return new ApplicationContextInitializer[] { new SpringAppContInit() } ;
    }
}

然而, ApplicationContextInitializer並沒有真正添加任何通過簡單設置環境或系統屬性無法完成的事情。

spring.profiles.active=SQLDev

當你這樣做時,你不需要那個初始化。

我也堅信您的@EnableJpaRepositories在錯誤的類上,您想要啟用這些的事實不應該取決於您的個人資料。

@ComponentScan(basePackages = "base package") @EntityScan(basePackages ="base package") @EnableJpaRepositories(basePackages = "base package")

使用此注釋,如果您使用的是 spring-data-jpa,則擴展 CrudRepository 或 PagingAndSortingRepository 而不是 JpaRepository。並且在 TestController 中給出這樣的自動裝配:

@Autowired(required = true) CategoryRepository catRepo; 還要檢查 Category 類型的 id 是否為BigDecimal

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM