Ich erhalte in meiner Spring-Startanwendung ständig den Fehler ConflictingBeanDefinitionException. Ich bin nicht ganz sicher, wie ich damit umgehen soll. Ich habe mehrere Klassen mit Annotationen von @Configuration, die beim Einrichten von Thymeleaf, Spring Security und Web helfen. Warum versucht die Anwendung, den homeController zweimal einzurichten? (und wo versucht es das zu tun?)
Der Fehler ist:
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]
Mein Spring Boot-Hauptanwendungsinitialisierer:
@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);
}
}
Meine Datenbank-Konfigurationsdatei:
@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();
}
}
Meine Thymeleaf-Konfigurationsdatei:
@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<IDialect> dialects = new HashSet<IDialect>();
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;
}
}
Meine Web-Konfigurationsklasse:
@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();
}
}
Mein Controller (bei der Installation des Controllers ist ein Fehler aufgetreten)
@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";
}
}
Was könnte den ConflictingBeanDefinitionException-Fehler für meine Controller-Klasse verursachen?
Wie ich herausgefunden habe, besteht die Lösung darin, die doppelte Initialisierung zu deaktivieren, indem ein Filter in den Komponentenscan aufgenommen wird. In meinem Fall:
@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);
}
}
Ich hatte das gleiche Problem, aber aus einem anderen Grund.
Dies kann auch vorkommen, wenn Sie Ihre Klassen in Ihrem Projekt verschieben und keine 'Säuberung' durchführen.
Ich benutze gradle mit Spring-Boot-Plugin. Jetzt laufe ich normalerweise:
$> ./gradlew clean bootRun
Ich hatte das gleiche Problem bei einem Spring-Integrationstest , als ich ihn mit InteliJ ausführte.
Nach einem Refactor war einer meiner Controller-Klasse tatsächlich im Verzeichnis / out/production/classes vorhanden, das seit Version 2017.2 ..__ das Standardausgabeverzeichnis für Intelij ist. Es ist build/classes), das Gradle Clean-Ziel hatte keine Auswirkungen.
Für mich bestand die Lösung darin, / out/production/classes manuell zu entfernen und meinen Integrationstest erneut auszuführen.
Für eine mögliche dauerhafte Lösung ohne 2 Ausgabeverzeichnisse siehe hier
Ich hatte das gleiche Problem mit einer generierten .war-Datei von Spring-Boot. Die genehmigte Lösung (Timothy Tutis eigene Lösung) hat für mich nicht ganz so funktioniert, wie sie ist, aber ich habe sie ein wenig optimiert, und sie hat funktioniert. Ich habe gerade die folgende Zeile zu meiner Application.Java hinzugefügt:
@ComponentScan(basePackages = { "com.mypackage" })
Als Referenz geht hier meine vollständige 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);
}
}
Ich habe dies bei mvn festgestellt, nachdem ich mehrere Ordnernamen und verwandte Paketnamen geändert hatte. Dann habe ich maven clean aufgetragen und wieder Springboot gefahren, alles gelöst:
mvn clean
mvn spring-boot:run
Es scheint, dass Sie zwei entityManagerFactory haben, eine, die Sie automatisch einrichten werden, und eine, die Sie als Bean programmatisch auflösen:
@Autowired
private LocalContainerEntityManagerFactoryBean entityManagerFactory;
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
...
}
Ich denke, Sie brauchen nur Ihre konfigurierte Factory in entityManagerFactory () -Methode.