2017-02-17 23 views
0

У меня есть проект Spring, где несколько бобин могут иметь одно и то же имя компонента.Suppress ConflictingBeanDefinitionException для @ComponentScan

Во избежание ошибки ConflictingBeanDefinitionException проект имеет переопределенный ContextNamespaceHandler.

public class ContextNamespaceHandler extends NamespaceHandlerSupport { 

    @Override 
    public void init() { 
     registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser() { 
      @Override 
      protected ClassPathBeanDefinitionScanner createScanner(XmlReaderContext readerContext, boolean useDefaultFilters) { 
       return new ClassPathBeanDefinitionScanner(readerContext.getRegistry(), useDefaultFilters) { 
        @Override 
        protected boolean checkCandidate(String beanName, BeanDefinition beanDefinition) throws IllegalStateException { 
         return true; 
        } 
       }; 
      } 
     }); 
    } 

} 

Я использую Swagger/Springfox генерировать API документацию для проекта.

@Configuration 
@EnableWebMvc 
@EnableSwagger2 
@ComponentScan(basePackages = { "some.package", "some.other.package" }) 
public class SwaggerConfig { 
    // ... 
} 

@ComponentScan вызывает ConflictingBeanDefinitionException как он используется по умолчанию ClassPathBeanDefinitionScanner вместо переопределенное один.

Caused by: org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'xxx' for bean class [xxx] conflicts with existing, non-compatible bean definition of same name and class [xxx] 
    at org.springframework.context.annotation.ClassPathBeanDefinitionScanner.checkCandidate(ClassPathBeanDefinitionScanner.java:320) 
    at org.springframework.context.annotation.ClassPathBeanDefinitionScanner.doScan(ClassPathBeanDefinitionScanner.java:259) 
    at org.springframework.context.annotation.ComponentScanAnnotationParser.parse(ComponentScanAnnotationParser.java:140) 
    at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:262) 
    at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:226) 
    at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:193) 
    at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:163) 
    ... 22 more 

Есть ли способ, чтобы переопределить ClassPathBeanDefinitionScanner используется @ComponentScan или другим способом подавить ConflictingBeanDefinitionException?

+0

Почему у вас есть несколько бобов с тем же определением? –

+0

@JeremyGrand Это проект, который разделен на общие и несколько частей, специфичных для клиента. Некоторые компоненты в деталях, зависящих от клиента, могут переопределять общие. – infranoise

+0

Имя/идентификатор bean-компонента уникально, вам может потребоваться переосмыслить, как определенные части клиента переопределяют общие части. Но эти другие ответы могут быть полезны: http://stackoverflow.com/a/28503680/7421645 и http://stackoverflow.com/a/24067601/7421645 – James

ответ

0

Лучший подход здесь, как правило, чтобы сделать каждое имя боба уникальным, указав имя боба в аннотации, то есть:

@Service("someService") 

Теперь вы можете указать имя компоненты, который вы хотите использовать, когда автоматическое связывание :

@Autowired 
@Qualifier("someService") 

Даже если переопределенные компоненты существуют для общих объектов, это часто является хорошей идеей, чтобы указать имя для того, чтобы провести четкое различие. Подавление исключений, как правило, считается неправдой. Надеюсь это поможет!