I use spring boot 2.5.2 to create a servlet web application, but I cannot find a way to override ClassPathBeanDefinitionScanner.checkCandidate() to resolve bean conflicts.
This issue is somewhat similar to spring-projects/spring-framework#13962.
Comment From: sbrannen
Have you considered registering a custom BeanNameGenerator to avoid conflicting bean names during component scanning?
If that does not work for you, what is the exact use case you have for wanting to override checkCandidate()?
Comment From: xiejx618
I want to make a bean override function. If there is a bean annotated with @ReplaceBean, then I can override the bean with the same bean name. In order to achieve the extended function of secondary development
Comment From: xiejx618
protected boolean checkCandidate(String beanName, BeanDefinition beanDefinition) throws IllegalStateException {
if (!this.registry.containsBeanDefinition(beanName)) {
return true;
}
BeanDefinition existingDef = this.registry.getBeanDefinition(beanName);
BeanDefinition originatingDef = existingDef.getOriginatingBeanDefinition();
if (originatingDef != null) {
existingDef = originatingDef;
}
ReplaceBean replaceAnnotation = replaceBeanAnnotation(beanDefinition.getBeanClassName());
if (replaceAnnotation != null) {
ReplaceBean existAnnotation = replaceBeanAnnotation(existingDef.getBeanClassName());
if (existAnnotation == null || replaceAnnotation.priority() > existAnnotation.priority()) {
this.registry.removeBeanDefinition(beanName);
this.registry.registerBeanDefinition(beanName, beanDefinition);
return true;
} else {
return false;
}
}
if (isCompatible(beanDefinition, existingDef)) {
return false;
}
throw new ConflictingBeanDefinitionException("Annotation-specified bean name '" + beanName +
"' for bean class [" + beanDefinition.getBeanClassName() + "] conflicts with existing, " +
"non-compatible bean definition of same name and class [" + existingDef.getBeanClassName() + "]");
}
Comment From: sbrannen
Unless I'm overlooking something, AnnotationConfigServletWebServerApplicationContext is from Spring Boot, and GenericWebApplicationContext in the core Spring Framework does not use a ClassPathBeanDefinitionScanner.
In light of that, I think the Spring Boot team should investigate the possible options here.
/cc @philwebb & @wilkinsona
Comment From: wilkinsona
I don't think it's possible at the moment. We could consider a AnnotationConfigServletWebServerApplicationContext constructor in Boot that allows the scanner to be passed in or, at the cost of the class's current immutability, a protected getter as Framework has in AnnotationConfigServletWebServerApplicationContext:
https://github.com/spring-projects/spring-framework/blob/d84ca2ba90d27a7c63d7b35a6259b5b9cf341118/spring-web/src/main/java/org/springframework/web/context/support/AnnotationConfigWebApplicationContext.java#L270-L282
I'll ask someone to transfer this to Boot.
Comment From: philwebb
We're cleaning out the issue tracker and closing issues that we've not seen much demand to fix. Feel free to comment with additional justifications if you feel that this one should not have been closed.