Spring Boot ConflictingBeanDefinitionException:@Controller类的注释指定bean名称

我一直在Spring启动应用程序中收到ConflictingBeanDefinitionException错误。 我不完全确定如何解决它,我有几个@Configuration注释类帮助建立Thymeleaf,Spring Security和Web。 为什么应用程序试图设置homeController两次? (它在哪里尝试这样做?)

错误是:

org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class [org.kemri.wellcome.hie.Application]; nested exception is org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'homeController' for bean class [org.kemri.wellcome.hie.HomeController] conflicts with existing, non-compatible bean definition of same name and class [org.kemri.wellcome.hie.controller.HomeController] 

我的spring boot主应用程序初始化程序:

 @EnableScheduling @EnableAspectJAutoProxy @EnableCaching @Configuration @ComponentScan @EnableAutoConfiguration public class Application extends SpringBootServletInitializer { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Override protected final SpringApplicationBuilder configure(final SpringApplicationBuilder application) { return application.sources(Application.class); } } 

我的数据库配置文件:

 @Configuration @EnableTransactionManagement @EnableJpaRepositories(basePackages="org.kemri.wellcome.hie.repositories") @PropertySource("classpath:application.properties") public class DatabaseConfig { @Autowired private Environment env; @Autowired private DataSource dataSource; @Autowired private LocalContainerEntityManagerFactoryBean entityManagerFactory; @Bean public DataSource dataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName(env.getProperty("spring.datasource.driverClassName")); dataSource.setUrl(env.getProperty("spring.datasource.url")); dataSource.setUsername(env.getProperty("spring.datasource.username")); dataSource.setPassword(env.getProperty("spring.datasource.password")); return dataSource; } @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactory() { LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean(); entityManagerFactory.setDataSource(dataSource); // Classpath scanning of @Component, @Service, etc annotated class entityManagerFactory.setPackagesToScan( env.getProperty("spring.jpa.hibernate.entitymanager.packagesToScan")); // Vendor adapter HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); entityManagerFactory.setJpaVendorAdapter(vendorAdapter); // Hibernate properties Properties additionalProperties = new Properties(); additionalProperties.put( "hibernate.dialect", env.getProperty("spring.jpa.hibernate.dialect")); additionalProperties.put( "hibernate.showsql", env.getProperty("spring.jpa.hibernate.showsql")); additionalProperties.put( "hibernate.hbm2ddl.auto", env.getProperty("spring.jpa.hibernate.hbm2ddl.auto")); entityManagerFactory.setJpaProperties(additionalProperties); return entityManagerFactory; } @Bean public JpaTransactionManager transactionManager() { JpaTransactionManager transactionManager = new JpaTransactionManager(); transactionManager.setEntityManagerFactory( entityManagerFactory.getObject()); return transactionManager; } @Bean public PersistenceExceptionTranslationPostProcessor exceptionTranslation() { return new PersistenceExceptionTranslationPostProcessor(); } } 

我的Thymeleaf配置文件:

 @Configuration public class ThymeleafConfig { @Bean public ServletContextTemplateResolver templateResolver(){ ServletContextTemplateResolver thymeTemplateResolver = new ServletContextTemplateResolver(); thymeTemplateResolver.setPrefix("/WEB-INF/views/"); thymeTemplateResolver.setSuffix(".html"); thymeTemplateResolver.setTemplateMode("HTML5"); return thymeTemplateResolver; } @Bean public SpringSecurityDialect springSecurityDialect(){ SpringSecurityDialect dialect = new SpringSecurityDialect(); return dialect; } @Bean public SpringTemplateEngine templateEngine() { SpringTemplateEngine engine = new SpringTemplateEngine(); engine.addTemplateResolver(templateResolver()); Set dialects = new HashSet(); dialects.add(springSecurityDialect()); engine.setAdditionalDialects(dialects); return engine; } @Bean public ThymeleafViewResolver thymeleafViewResolver() { ThymeleafViewResolver resolver = new ThymeleafViewResolver(); resolver.setTemplateEngine(templateEngine()); resolver.setViewClass(ThymeleafTilesView.class); resolver.setCharacterEncoding("UTF-8"); return resolver; } 

}

我的Web配置类:

 @Configuration @PropertySource("classpath:application.properties") public class WebConfig extends WebMvcAutoConfigurationAdapter { @Autowired private Environment env; @Bean public JavaMailSenderImpl javaMailSenderImpl() { JavaMailSenderImpl mailSenderImpl = new JavaMailSenderImpl(); mailSenderImpl.setHost(env.getProperty("smtp.host")); mailSenderImpl.setPort(env.getProperty("smtp.port", Integer.class)); mailSenderImpl.setProtocol(env.getProperty("smtp.protocol")); mailSenderImpl.setUsername(env.getProperty("smtp.username")); mailSenderImpl.setPassword(env.getProperty("smtp.password")); Properties javaMailProps = new Properties(); javaMailProps.put("mail.smtp.auth", true); javaMailProps.put("mail.smtp.starttls.enable", true); mailSenderImpl.setJavaMailProperties(javaMailProps); return mailSenderImpl; } @Bean public CacheManager cacheManager() { return new ConcurrentMapCacheManager(); } } 

我的控制器(设置控制器时出错)

 @Controller public class HomeController { private static final Logger logger = LoggerFactory.getLogger(HomeController.class); /** * Simply selects the home view to render by returning its name. */ @RequestMapping(value = "/", method = RequestMethod.GET) public String home(Locale locale, Model model) { logger.info("Welcome home! The client locale is {}.", locale); Date date = new Date(); DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale); String formattedDate = dateFormat.format(date); model.addAttribute("serverTime", formattedDate ); return "index.html"; } } 

什么可能导致我的控制器类出现ConflictingBeanDefinitionException错误?

我遇到了同样的问题,但原因不同。

如果您在项目中移动类并且无法执行“清理”,也会发生这种情况。

我使用gradle和spring-boot插件。 现在我经常跑:

 $> ./gradlew clean bootRun 

我发现,解决方案是通过在组件扫描中包含一个filter来禁用双初始化。 就我而言:

 @EnableScheduling @EnableAspectJAutoProxy @EnableCaching @Configuration @ComponentScan(basePackages = { "org.kemri.wellcome.hie" }, excludeFilters = {@Filter(value = Controller.class, type = FilterType.ANNOTATION)}) @EnableAutoConfiguration @PropertySource("classpath:application.properties") public class Application extends SpringBootServletInitializer { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } 

当我使用InteliJ运行它时,我在 Spring集成测试中遇到了同样的问题。

在重构之后,我的一个控制器类实际上在/ out / production / classes目录中是重复的,这是自2017.2版以来Intelij的默认输出目录。 由于gradle输出目录不同(它的构建/类 ),因此gradle clean目标无效。

对我来说,解决方案是手动删除/ out / production / classes并重新运行我的集成测试。

对于没有2个输出目录的可能持久解决方案,请参见此处

看来你有两个entityManagerFactory,一个你将自动assembly,一个你以编程方式解析为Bean:

 @Autowired private LocalContainerEntityManagerFactoryBean entityManagerFactory; @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactory() { ... } 

我想你只需要在entityManagerFactory()方法中配置工厂。

我从spring-boot生成的.war文件遇到了同样的问题。 批准的解决方案(Timothy Tuti自己的解决方案)对我来说并不完全正常,但我稍微调整了一下它就有效了。 我刚刚将以下行添加到我的Application.java中:

@ComponentScan(basePackages = { "com.mypackage" })

作为参考,这里是我的完整Application.java

 package com.inmoment.devchallenge; import org.neo4j.graphdb.GraphDatabaseService; import org.neo4j.graphdb.factory.GraphDatabaseFactory; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.context.web.SpringBootServletInitializer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.data.neo4j.config.EnableNeo4jRepositories; import org.springframework.data.neo4j.config.Neo4jConfiguration; @SpringBootApplication @Configuration @ComponentScan(basePackages = { "com.inmoment.devchallenge.controller" }) @EnableAutoConfiguration public class Application extends SpringBootServletInitializer { @Configuration @EnableNeo4jRepositories(basePackages = "com.inmoment.devchallenge.repository") static class ApplicationConfig extends Neo4jConfiguration { public ApplicationConfig() { setBasePackage("com.inmoment.devchallenge.repository"); } @Bean GraphDatabaseService graphDatabaseService() { return new GraphDatabaseFactory().newEmbeddedDatabase("accessingdataneo4j.db"); } } @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(Application.class); } public static void main(String[] args) throws Exception { SpringApplication.run(Application.class, args); } }