NoSuchBeanDefinitionException:没有为依赖项找到类型的限定bean:预期至少有1个bean有资格作为autowire

我发现类似的问题解释了很多门户网站。 但我想这是独特的情况。 我在spring mvc app中收到错误。

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 { @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 properties = new HashMap(); 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 testJ(){ return catRepo.findAll(); } } 

CategoryRepository:

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

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

编辑:(因为有很多评论添加到此,考虑添加这些细节)

我指的是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隐式地进行注册。现在我正在寻找上述代码无效的原因。 我有一些解决方法,我可以通过恢复到XML或WebApplicationInitializer来使其工作。 我正在寻找一个解决方案,并尽可能使用更新的代码而不是API文档。 我需要一个教程。 API文档不会帮助我解决问题。

您自己的WebApplicationInitializer实现和扩展AbstractAnnotationConfigDispatcherServletInitializer的实现是不同的。 它们表现不同,这是因为您没有注册自定义ApplicationContextInitializer 。 如何注册ApplicationContextInitializer在javadoc中进行了解释(注意2个方法来设置ApplicationContextInitializer的集合。)。

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

但是, ApplicationContextInitializer并不能通过简单地设置环境或系统属性来添加任何无法完成的操作。

 spring.profiles.active=SQLDev 

当你这样做时,你不需要那个init。

我也坚信你的@EnableJpaRepositories是在错误的类上,你想要启用它们的事实不应该依赖于你的个人资料。

@ComponentScan(basePackages =“base package”)@ EntityScan(basePackages =“base package”)@ EnableJpaRepositories(basePackages =“base package”)

使用这个注释,如果你使用的是spring-data-jpa,那么扩展CrudRepository或PagingAndSortingRepository而不是JpaRepository.And在TestController中给出自动assembly,如下所示:

@Autowired(required = true)CategoryRepository catRepo; 同时检查Category是否为BigDecimal类型的id。