当前位置: 首页 > 知识库问答 >
问题:

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

宰父宾实
2023-03-14

我在Spring boot应用程序中不断遇到冲突BeanDefinitionException错误。我不完全确定如何解决这个问题,我有几个带注释的类来帮助设置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<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;
}

}

我的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";
    }
}

是什么导致我的控制器类出现冲突BeanDefinitionException错误?

共有3个答案

景远航
2023-03-14

正如我所发现的,解决方案是通过在组件扫描中包含过滤器来禁用双重初始化。在我的情况下:

@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);
    }
}
云远
2023-03-14

当我使用InteliJ运行Spring联调时,我也遇到了同样的问题。

重构后,我的一个控制器类实际上在 /out/production/classes目录中重复,这是Intelij自2017.2版以来的默认输出目录。由于gradle输出目录不同(它是build/class),gradle清洁目标没有影响。

对我来说,解决方案是手动删除 /out/production/classes并重新运行联调。

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

麻和雅
2023-03-14

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

如果您在项目中移动类,但没有进行“清理”,也可能发生这种情况。

我使用gradle和sping-boot插件。现在我通常运行:

$> ./gradlew clean bootRun
 类似资料:
  • 我在一些Spring bean定义上遇到了问题。我的main()方法加载了两个上下文xml文件,它们几乎都只包含一个标记。当我的main方法启动时,我从Spring中得到以下错误: -迈克

  • 我有一个被注释为的类,然后将其添加到另一个类中。但是,我需要删除这个注释,而是在以前自动连线它的类中用一个注释方法创建它。 以前的类看起来像: ...或者我直接调用这个方法(在我看来不是正确的方法): …或者这两个都不正确?

  • 这些是实现控制器类 然而,当我们在Spring MVC程序中使用@Controller注释时,如何知道我们的@Controller注释正在实现这些控制器中的任何一个

  • 我刚刚发现了一种我无法理解的Spring的行为。我使用的是Spring Boot 1.5。十、 在一个配置类中,我声明了两个不同的bean。 然后,我有一个类,它应该使用名为的bean。 因为我指定了我想要使用注释注入的bean的名称,所以我希望Spring注入名为的bean。但是,在注入过程中实际上使用了名为的bean。 事实证明,问题在于在配置类中声明bean的方法的名称。两者都是colled

  • 问题内容: 我目前正在创建一个有趣的python线性代数模块,并使用该语言进行实践。我最近尝试将类型注释添加到模块中,如下所示: 但是,当我尝试导入它时,它吐出一个。我承认这个问题已经在这里以某种形式得到了回答,但似乎并不能完全解决我的情况。 我想知道的是: 我已经在该文件中按字面值定义了该类。为什么说未定义名称? 如何定义可用于注释的方式(作为)? 问题答案: 您有一份前瞻性声明;函数(作为方法

  • 问题内容: 有什么方法可以通过JPA注释指定SQL注释?表和列的注释。 问题答案: 有什么方法可以通过JPA注释指定SQL注释?表和列的注释。 否。如果要定义表和列注释,最好的选择是在生成的DDL中根据事实进行操作,然后再对数据库执行操作。