spring-framework icon indicating copy to clipboard operation
spring-framework copied to clipboard

Consider allowing to exclude some beans from AOT processed applications

Open philwebb opened this issue 2 years ago • 9 comments

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.

philwebb avatar Nov 14 '22 20:11 philwebb

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

wilkinsona avatar Nov 30 '22 11:11 wilkinsona

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.

sdeleuze avatar Jan 17 '23 11:01 sdeleuze

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;
	}

}

dsyer avatar Feb 01 '23 09:02 dsyer

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.

sdeleuze avatar Feb 02 '23 14:02 sdeleuze

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)));
	  }
}

mmarimuthu avatar Apr 04 '24 12:04 mmarimuthu

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

dsyer avatar Apr 04 '24 12:04 dsyer

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

snicoll avatar Apr 04 '24 12:04 snicoll

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

@dsyer here is the sample

@ aot-issue.zip

mmarimuthu avatar Apr 04 '24 16:04 mmarimuthu

@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.

snicoll avatar Jul 29 '24 13:07 snicoll