See https://github.com/spring-projects/spring-boot/issues/32262 for background.

Currently we have a number of areas where we want to exclude beans from being used in AOT processed applications. There are a number of ways we currently do this.

  • If a bean implements BeanRegistrationAotProcessor then the isBeanExcludedFromAotProcessing result is considered.
  • If we want to filter a bean, we can use BeanRegistrationExcludeFilter in META-INF/spring/aot.factories.
  • For most other situations we use an if with AotDetector.useGeneratedArtifacts() in the actual code.

It would be nice if we could review these existing usages and see if we can find a common way to perform exclusions.

Comment From: wilkinsona

https://github.com/spring-projects/spring-boot/issues/33374 is another example of beans that aren't needed after AOT processing.

Comment From: sdeleuze

I tentatively schedule this issue for Spring Framework 6.1.0-M1 along to #29555 as they are related and it is important to move forward on this topic.

Comment From: dsyer

Can this be implemented in a way that doesn't require me to use an annotation? I might want to manage bean definitions for classes that I didn't write or have no control over the annotations on. E.g. register bean definitions with a well-known attribute that says "I have a supplier already, you don't need to generate any code for me". I can already do this kind of manually, and it works in my use case, by registering a BeanRegistrationExcludeFilter in aot.factories. Example:

public class ExcludeFilter implements BeanRegistrationExcludeFilter {

    static final String IGNORE_ME = "ignore.me";

    @Override
    public boolean isExcludedFromAotProcessing(RegisteredBean registeredBean) {
        if (registeredBean.getMergedBeanDefinition().hasAttribute(IGNORE_ME)) {
            return true;
        }
        return false;
    }

}

Comment From: sdeleuze

I also would like to avoid making annotation mandatory to manage this kind of concept, just not sure yet what we should use. See also use case in #29555 where annotation may not be ideal. I will discuss with @jhoeller the related design we should use.

Comment From: mmarimuthu

I tried applying filter as suggested by @dsyer but no luck. let me know if the implementation is wrong.

public class CloudFunctionSample implements Function<Map<String, Object>, Map<String, Object>> {

    private String hasAttribute = "ignore.me";
...
}

Main:

// other annotations
@SpringBootConfiguration
@ComponentScan(basePackages = { "com.myorg" }, excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = ExcludeFilter.class))
public class CredentialingJobApplication implements ApplicationContextInitializer<GenericApplicationContext> {

    public static void main(String[] args) {
        FunctionalSpringApplication app = new FunctionalSpringApplication(CredentialingJobApplication.class);
        app.run(args);
    }

    @Override
      public void initialize(GenericApplicationContext context) {
        context.registerBean("cloudFunctionOne", FunctionRegistration.class,
            () -> new FunctionRegistration<>(new CloudFunctionSample())
                .type(FunctionTypeUtils.functionType(Map.class, Map.class)));
      }
}

Comment From: dsyer

You didn't really show a complete sample. Maybe if you post a minimal reproducer we could inspect it and decide one way or the other? It doesn't look like you add the "ignore.me" attribute to your bean definition (I assume it is the FunctionRegistration)?

Comment From: snicoll

@mmarimuthu please stop asking the same question on multiple issue trackers. Refer to StackOverflow or the documentation.

Comment From: mmarimuthu

@snicoll I apologize for the concern. I will try to improve.

@dsyer here is the sample

@ aot-issue.zip

Comment From: snicoll

@dsyer yes, as of 6.2, you can set BeanRegistrationAotProcessor.IGNORE_REGISTRATION_ATTRIBUTE to true on the bean definition. I think this issue is really about two different things. There is the cases where a bean is excluded, and there's the case where a component that register beans is invoked twice. These are fairly different and, while I think we've made so good progress for the former, we really didn't for the latter.