when using @Value
or @Autowired
inside a @Webfilter
annotationed class and run in aot mode, it'll raise error
***************************
APPLICATION FAILED TO START
***************************
Description:
A component required a bean named '(inner bean)#5884a914' that could not be found.
Action:
Consider defining a bean named '(inner bean)#5884a914' in your configuration.
spring boot version 3.0.1
example project here demo.zip
seems in org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#obtainInstanceFromSupplier
if (supplier instanceof InstanceSupplier<?> instanceSupplier) {
return instanceSupplier.get(RegisteredBean.of((ConfigurableListableBeanFactory) this, beanName));
}
inner beans can't be found by beanName, but WebFilterHandler uses inner bean to create filter.
Comment From: sdeleuze
I can indeed reproduce the issue.
Comment From: sdeleuze
@bclozel cc @wilkinsona If I upgrade the repro to Spring Boot 3.0.3
, I see the following error:
Exception in thread "main" java.lang.IllegalArgumentException: Code generation is not supported for bean definitions declaring an instance supplier callback : Root bean: class [org.springframework.boot.web.servlet.ServletComponentRegisteringPostProcessor]; scope=singleton; abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodNames=null; destroyMethodNames=null
at org.springframework.beans.factory.aot.BeanDefinitionMethodGenerator.<init>(BeanDefinitionMethodGenerator.java:82)
at org.springframework.beans.factory.aot.BeanDefinitionMethodGeneratorFactory.getBeanDefinitionMethodGenerator(BeanDefinitionMethodGeneratorFactory.java:100)
at org.springframework.beans.factory.aot.BeanDefinitionMethodGeneratorFactory.getBeanDefinitionMethodGenerator(BeanDefinitionMethodGeneratorFactory.java:115)
I am wondering if ServletComponentRegisteringPostProcessor
needs special handling via an AOT processor like we did for similar cases, so maybe this issue should be moved back to Boot?
Comment From: wilkinsona
We definitely need to do something in Boot. ServletComponentRegisteringPostProcessor
shouldn't be needed in an AOT-processed context as it would only try to register its beans again. It can be excluded with a BeanRegistrationExcludeFilter
registered in META-INF/spring/aot.factories
:
class ServletComponentRegisteringPostProcessorExcludeFilter implements BeanRegistrationExcludeFilter {
@Override
public boolean isExcludedFromAotProcessing(RegisteredBean registeredBean) {
return "servletComponentRegisteringPostProcessor".equals(registeredBean.getBeanName());
}
}
We then get back to the original failure:
***************************
APPLICATION FAILED TO START
***************************
Description:
A component required a bean named '(inner bean)#61dbfa83' that could not be found.
Action:
Consider defining a bean named '(inner bean)#61dbfa83' in your configuration.
It would certainly be nice if Framework could support this arrangement but I don't know if that's possible. The code that's generated inFilterRegistrationBean__BeanDefinitions
, TestFilter__BeanDefinitions
, and TestFilter__Autowiring
looks pretty good to me and it would be a shame if Boot had to use some custom generation.
Could you please explore what's possible on the Framework side when the exclude filter's in place? That will hopefully allow us to figure out if we just need the exclusion built into Boot, and Framework can tackle the rest of the problem, or if we need more extensive changes in Boot.
Comment From: wilkinsona
Thanks, @jhoeller.
With Framework 6.0.7 snapshots and the exclude filter described above the problem no longer occurs. I've opened https://github.com/spring-projects/spring-boot/issues/34563 so that Boot takes care of the exclusion automatically.
Comment From: zcw159357
Thank you all for the work!!