Skip to content

Allow custom ClassPathBeanDefinitionScanner on AnnotationConfigServletWebServerApplicationContext #29294

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
xiejx618 opened this issue Jan 1, 2022 · 6 comments
Labels
status: declined A suggestion or change that we don't feel we should currently apply

Comments

@xiejx618
Copy link

xiejx618 commented Jan 1, 2022

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.

@sbrannen
Copy link
Member

sbrannen commented Jan 3, 2022

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()?

@xiejx618
Copy link
Author

xiejx618 commented Jan 7, 2022

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

@xiejx618
Copy link
Author

xiejx618 commented Jan 7, 2022

    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() + "]");
    }

@sbrannen sbrannen changed the title Jan 7, 2022
@sbrannen sbrannen changed the title Jan 7, 2022
@sbrannen
Copy link
Member

sbrannen commented Jan 7, 2022

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

@wilkinsona
Copy link
Member

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.

@bclozel bclozel transferred this issue from spring-projects/spring-framework Jan 7, 2022
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Jan 7, 2022
@philwebb philwebb added the for: team-attention An issue we'd like other members of the team to review label Jan 7, 2022
@philwebb
Copy link
Member

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.

@philwebb philwebb closed this as not planned Won't fix, can't repro, duplicate, stale Aug 24, 2022
@philwebb philwebb added status: declined A suggestion or change that we don't feel we should currently apply and removed for: team-attention An issue we'd like other members of the team to review status: waiting-for-triage An issue we've not yet triaged labels Aug 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: declined A suggestion or change that we don't feel we should currently apply
Projects
None yet
Development

No branches or pull requests

5 participants