2015-02-13 21 views
8

Tôi tiếp tục nhận được lỗi ConflictingBeanDefinitionException trong ứng dụng khởi động Spring của tôi. Tôi không hoàn toàn chắc chắn như thế nào để giải quyết nó, tôi có một số @Configuration chú thích các lớp học giúp thiết lập Thymeleaf, Spring Security và Web. Tại sao ứng dụng lại cố gắng thiết lập homeController hai lần? (? Và ở đâu là nó cố gắng để làm điều này)Spring Boot ConflictingBeanDefinitionException: Tên đậu được chỉ định chú thích cho lớp @Controller

Lỗi này là:

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] 

khởi động mùa xuân của tôi chính ứng dụng khởi tạo:

@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); 
    } 

} 

My CSDL config file:

@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(); 
    } 

} 

Tệp cấu hình Thymeleaf của tôi:

@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; 
} 

}

My lớp Web config:

@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(); 
    } 
} 

điều khiển của tôi (nơi có một lỗi thiết lập bộ điều khiển)

@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"; 
    } 
} 

Điều gì có thể gây ra lỗi ConflictingBeanDefinitionException cho tôi lớp điều khiển?

+0

Hãy thử thêm ** @ EnableWebMvc ** trên _WebConfig.class_ – lgd

+0

Điều đó không có tác dụng. Tôi vẫn gặp lỗi tương tự. –

Trả lời

5

Giải pháp, như tôi phát hiện ra, là vô hiệu hóa khởi tạo kép bằng cách bao gồm một bộ lọc trong quá trình quét thành phần. Trong trường hợp của tôi:

@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); 
    } 
} 
+1

Bạn đã phát hiện chính xác cách khởi tạo kép (ngoại trừ từ dấu vết ngăn xếp) ở đâu? Bạn có tìm ra nguyên nhân không? – lgd

0

Dường như bạn có hai entityManagerFactory, một trong những bạn sẽ autowire và một bạn giải quyết lập trình như Bean:

@Autowired 
private LocalContainerEntityManagerFactoryBean entityManagerFactory; 

@Bean 
public LocalContainerEntityManagerFactoryBean entityManagerFactory() { 
... 
} 

Tôi nghĩ rằng bạn chỉ cần máy cấu hình của bạn trong entityManagerFactory() phương pháp.

+0

Vẫn gặp lỗi tương tự. –

+0

Bạn không cần phải ghi đè lên phương thức cấu hình trong Lớp Ứng dụng của bạn, bởi vì Lớp của bạn chính nó là một Ứng dụng. –

+0

Tôi đã gỡ bỏ chức năng cấu hình trong lớp ứng dụng chính và tôi vẫn gặp lỗi tương tự. –

0

Tôi đã gặp sự cố tương tự với tệp .war được tạo ra từ khởi động mùa xuân. giải pháp được phê duyệt (giải pháp riêng của Timothy Tuti) không hoàn toàn phù hợp với tôi, nhưng tôi đã chỉnh sửa nó một chút và nó hoạt động. Tôi chỉ cần thêm dòng sau vào Application.java tôi:

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

Để tham khảo, ở đây đi đầy đủ Application.java tôi

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); 
    } 

} 
12

Tôi chạy vào cùng một vấn đề nhưng vì một lý do khác nhau.

Điều này cũng có thể xảy ra nếu bạn di chuyển các lớp của bạn xung quanh trong dự án của bạn và không làm một 'sạch'.

Tôi sử dụng gradle với plugin khởi động mùa xuân. Bây giờ tôi thường chạy:

$> ./gradlew clean bootRun 
+1

Tôi nghĩ đây là câu trả lời đúng. Các giải pháp được chấp nhận cũng giúp, nhưng nó rất có thể gây ra bởi dữ liệu cũ cũng có. –

Các vấn đề liên quan