0

I have a Spring project where multiple beans may have the same bean name.

In order to avoid ConflictingBeanDefinitionException the project has an overridden 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;
                    }
                };
            }
        });
    }

}

I'm using Swagger/Springfox to generate API documentation for the project.

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

@ComponentScan is causing ConflictingBeanDefinitionException as it is using default ClassPathBeanDefinitionScanner instead of the overridden one.

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

Is there a way to override ClassPathBeanDefinitionScanner used by @ComponentScan or other way to suppress ConflictingBeanDefinitionException?

infranoise
  • 277
  • 4
  • 18
  • Why would you have multiple beans with the same definition ? – Jeremy Grand Feb 17 '17 at 16:09
  • @JeremyGrand It's a project that is split into a generic and multiple customer-specific parts. Some components in customer-specific parts may override generic ones. – infranoise Feb 17 '17 at 16:11
  • The bean name/id is unique, you might want to rethink how the customer specific parts override the generic parts. But these other answers might be helpful: http://stackoverflow.com/a/28503680/7421645 and http://stackoverflow.com/a/24067601/7421645 – James Feb 17 '17 at 16:22

1 Answers1

0

The best approach here is usually to make each bean name unique by specifying the bean name in the annotation, i.e.:

@Service("someService")

Now, you can specify the name of the bean you want to use when autowiring:

@Autowired
@Qualifier("someService")

Even if overridden components exist for generic objects, it's often a good idea to specify a name in order to make a clear distinction. Suppressing exceptions is typically considered to not be good practice. Hope this helps!

inokien
  • 26
  • 4