Many people suggest using @org.springframework.context.annotation.Lazy in issues. Spring Team has never suggested using @org.springframework.context.annotation.Lazy, and this annotation is totally against people's intuition.@org.springframework.context.annotation.Lazy also requires additional GraalVM Reachability Metadata JSON under GraalVM Native Image, which further proves the uselessness of this annotation. See Juergen Hoeller's comments on this. Refer to https://github.com/spring-projects/spring-framework/issues/29584 .
I generally recommend avoiding proxies for lazy-resolution purposes since this can always be replaced with a lightweight ObjectProvider arrangement. Or in this case, with a full-scale scoped proxy bean which is more efficient as well (since it is not on-demand per constructor but rather shared application-wide).
The current PR will solve the following Error Log once and for all.
java.lang.IllegalStateException: Failed to load ApplicationContext for [WebMergedContextConfiguration@383cb5ce testClass = org.apache.shardingsphere.elasticjob.test.natived.SpirngBootTest, locations = [], classes = [org.apache.shardingsphere.elasticjob.test.natived.ElasticJobSpringBootStarterApplication], contextInitializerClasses = [], activeProfiles = [], propertySourceDescriptors = [PropertySourceDescriptor[locations=[classpath:application.yml], ignoreResourceNotFound=false, name=null, propertySourceFactory=null, encoding=null]], propertySourceProperties = ["org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true", "server.port=0"], contextCustomizers = [org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@82de64a, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@61001b64, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@52b1beb6, org.springframework.boot.test.web.reactor.netty.DisableReactorResourceFactoryGlobalResourcesContextCustomizerFactory$DisableReactorResourceFactoryGlobalResourcesContextCustomizerCustomizer@5d534f5d, org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizer@4145bad8, org.springframework.test.context.support.DynamicPropertiesContextCustomizer@e02884ba, org.springframework.boot.test.context.SpringBootTestAnnotation@e8291591], resourceBasePath = "src/main/webapp", contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:180)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:130)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:142)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:98)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:260)
at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:163)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:212)
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:194)
at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1709)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:556)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:546)
at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:310)
at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735)
at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734)
at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:782)
at java.base/java.util.Optional.orElseGet(Optional.java:364)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1597)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1597)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'oneOffJobController': Injection of resource dependencies failed
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessProperties(CommonAnnotationBeanPostProcessor.java:371)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1439)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:599)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:337)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:335)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:975)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:971)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:625)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:335)
at org.springframework.boot.test.context.SpringBootContextLoader.lambda$loadContext$3(SpringBootContextLoader.java:137)
at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:58)
at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:46)
at org.springframework.boot.SpringApplication.withHook(SpringApplication.java:1463)
at org.springframework.boot.test.context.SpringBootContextLoader$ContextLoaderHook.run(SpringBootContextLoader.java:553)
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:137)
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:108)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:225)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:152)
... 17 more
Caused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class org.apache.shardingsphere.elasticjob.bootstrap.type.OneOffJobBootstrap: Common causes of this problem include using a final class or a non-visible class
at org.springframework.aop.framework.CglibAopProxy.buildProxy(CglibAopProxy.java:230)
at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:163)
at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:110)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.buildLazyResourceProxy(CommonAnnotationBeanPostProcessor.java:542)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:737)
at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:270)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:145)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessProperties(CommonAnnotationBeanPostProcessor.java:368)
... 40 more
Caused by: java.lang.IllegalArgumentException: Cannot subclass final class org.apache.shardingsphere.elasticjob.bootstrap.type.OneOffJobBootstrap
at org.springframework.cglib.proxy.Enhancer.generateClass(Enhancer.java:653)
at org.springframework.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:26)
at org.springframework.cglib.core.ClassLoaderAwareGeneratorStrategy.generate(ClassLoaderAwareGeneratorStrategy.java:57)
at org.springframework.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:366)
at org.springframework.cglib.proxy.Enhancer.generate(Enhancer.java:575)
at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.lambda$new$1(AbstractClassGenerator.java:107)
at org.springframework.cglib.core.internal.LoadingCache.lambda$createEntry$1(LoadingCache.java:52)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
at org.springframework.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:57)
at org.springframework.cglib.core.internal.LoadingCache.get(LoadingCache.java:34)
at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator.java:130)
at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:317)
at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:562)
at org.springframework.cglib.proxy.Enhancer.createClass(Enhancer.java:407)
at org.springframework.aop.framework.ObjenesisCglibAopProxy.createProxyClassAndInstance(ObjenesisCglibAopProxy.java:62)
at org.springframework.aop.framework.CglibAopProxy.buildProxy(CglibAopProxy.java:221)
... 47 more
Fixes #2014 .
Changes proposed in this pull request:
jakarta.annotation.Resource
should be avoided in Spring Boot. Spring Boot's Context has more useful tool classes.@org.springframework.context.annotation.Lazy
in issues. Spring Team has never suggested using@org.springframework.context.annotation.Lazy
, and this annotation is totally against people's intuition.@org.springframework.context.annotation.Lazy
also requires additional GraalVM Reachability Metadata JSON under GraalVM Native Image, which further proves the uselessness of this annotation. See Juergen Hoeller's comments on this. Refer to https://github.com/spring-projects/spring-framework/issues/29584 .