Spring Boot / Spring AOP: AutoProxyRegistrar.class 无法打开,因为它不存在

Spring Boot / Spring AOP: AutoProxyRegistrar.class cannot be opened because it does not exist

我有一个 2.2.13 多租户应用程序。我正在为每个租户创建多个 Spring 上下文,加上主上下文和另一个上下文。因此,应该加载 n+2 个上下文,其中 n 是租户的数量。 我有两种模式来生成租户上下文,串行(在应用程序的主线程中)或使用 ExecutorService 并行。

在开发过程中,我正在使用 spring-boot-maven-plugin:run 并且所有租户上下文都按预期顺序或并行加载。

但是,在生产中,我将应用程序部署并启动为带有 java -jar 的常规 fat-jar 应用程序,但并非所有上下文都已加载。错误的上下文是我们尝试从工作线程启动的上下文。从主线程加载的任何上下文都可以。错误是 class path resource [org/springframework/context/annotation/AutoProxyRegistrar.class] cannot be opened because it does not exist 异常。

2021-10-29 09:43:03.724  WARN 8260 --- [onPool-worker-3] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to process import candidates for configuration class [com.piag.products.Application]; nested exception is java.io.FileNotFoundException: class path resource [org/springframework/context/annotation/AutoProxyRegistrar.class] cannot be opened because it does not exist
2021-10-29 09:43:03.737 ERROR 8260 --- [onPool-worker-3] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.BeanDefinitionStoreException: Failed to process import candidates for configuration class [com.piag.products.Application]; nested exception is java.io.FileNotFoundException: class path resource [org/springframework/context/annotation/AutoProxyRegistrar.class] cannot be opened because it does not exist
        at org.springframework.context.annotation.ConfigurationClassParser.processImports(ConfigurationClassParser.java:610) ~[spring-context-5.2.12.RELEASE.jar!/:5.2.12.RELEASE]
        at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:311) ~[spring-context-5.2.12.RELEASE.jar!/:5.2.12.RELEASE]
        at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:250) ~[spring-context-5.2.12.RELEASE.jar!/:5.2.12.RELEASE]
        at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:207) ~[spring-context-5.2.12.RELEASE.jar!/:5.2.12.RELEASE]
        at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:175) ~[spring-context-5.2.12.RELEASE.jar!/:5.2.12.RELEASE]
        at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:319) ~[spring-context-5.2.12.RELEASE.jar!/:5.2.12.RELEASE]
        at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:236) ~[spring-context-5.2.12.RELEASE.jar!/:5.2.12.RELEASE]
        at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:280) ~[spring-context-5.2.12.RELEASE.jar!/:5.2.12.RELEASE]
        at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:96) ~[spring-context-5.2.12.RELEASE.jar!/:5.2.12.RELEASE]
        at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:707) ~[spring-context-5.2.12.RELEASE.jar!/:5.2.12.RELEASE]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:533) ~[spring-context-5.2.12.RELEASE.jar!/:5.2.12.RELEASE]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747) ~[spring-boot-2.2.13.RELEASE.jar!/:2.2.13.RELEASE]
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:405) ~[spring-boot-2.2.13.RELEASE.jar!/:2.2.13.RELEASE]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) ~[spring-boot-2.2.13.RELEASE.jar!/:2.2.13.RELEASE]
        at com.piag.products.IPRunner.startUpTenantContext(IPRunner.java:377) ~[app-1.0-SNAPSHOT.jar!/:1.0-SNAPSHOT]
        at com.piag.products.IPRunner.startTenantCustomerExecutionContext(IPRunner.java:358) ~[app-1.0-SNAPSHOT.jar!/:1.0-SNAPSHOT]
        at com.piag.products.IPRunner.lambda$doStartTenantCustomerExecutionContext(IPRunner.java:322) ~[app-1.0-SNAPSHOT.jar!/:1.0-SNAPSHOT]
        at java.base/java.util.stream.ReferencePipeline.accept(ReferencePipeline.java:195) ~[na:na]
        at java.base/java.util.concurrent.ConcurrentHashMap$KeySpliterator.forEachRemaining(ConcurrentHashMap.java:3566) ~[na:na]
        at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484) ~[na:na]
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474) ~[na:na]
        at java.base/java.util.stream.ReduceOps$ReduceTask.doLeaf(ReduceOps.java:952) ~[na:na]
        at java.base/java.util.stream.ReduceOps$ReduceTask.doLeaf(ReduceOps.java:926) ~[na:na]
        at java.base/java.util.stream.AbstractTask.compute(AbstractTask.java:327) ~[na:na]
        at java.base/java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:746) ~[na:na]
        at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290) ~[na:na]
        at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020) ~[na:na]
        at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656) ~[na:na]
        at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594) ~[na:na]
        at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183) ~[na:na]
Caused by: java.io.FileNotFoundException: class path resource [org/springframework/context/annotation/AutoProxyRegistrar.class] cannot be opened because it does not exist
        at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:180) ~[spring-core-5.2.12.RELEASE.jar!/:5.2.12.RELEASE]
        at org.springframework.core.type.classreading.SimpleMetadataReader.getClassReader(SimpleMetadataReader.java:55) ~[spring-core-5.2.12.RELEASE.jar!/:5.2.12.RELEASE]
        at org.springframework.core.type.classreading.SimpleMetadataReader.<init>(SimpleMetadataReader.java:49) ~[spring-core-5.2.12.RELEASE.jar!/:5.2.12.RELEASE]
        at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:103) ~[spring-core-5.2.12.RELEASE.jar!/:5.2.12.RELEASE]
        at org.springframework.core.type.classreading.CachingMetadataReaderFactory.getMetadataReader(CachingMetadataReaderFactory.java:123) ~[spring-core-5.2.12.RELEASE.jar!/:5.2.12.RELEASE]
        at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:81) ~[spring-core-5.2.12.RELEASE.jar!/:5.2.12.RELEASE]
        at org.springframework.context.annotation.ConfigurationClassParser.asSourceClass(ConfigurationClassParser.java:696) ~[spring-context-5.2.12.RELEASE.jar!/:5.2.12.RELEASE]
        at org.springframework.context.annotation.ConfigurationClassParser.asSourceClasses(ConfigurationClassParser.java:675) ~[spring-context-5.2.12.RELEASE.jar!/:5.2.12.RELEASE]
        at org.springframework.context.annotation.ConfigurationClassParser.processImports(ConfigurationClassParser.java:582) ~[spring-context-5.2.12.RELEASE.jar!/:5.2.12.RELEASE]
        ... 29 common frames omitted

我启动应用程序的方式是一样的。您可以看到 internalAutoProxyCreator 没有在错误的上下文中注册。

spring-boot:run 一切都很好。 7 个上下文/ 7 internalAutoProxyCreator 已注册。

$ mvn spring-boot:run -Dspring-boot.run.arguments=--logging.level.org.springframework=DEBUG |grep internalAutoProxyCreator
2021-10-28 21:32:05.612 DEBUG 18068 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'org.springframework.aop.config.internalAutoProxyCreator'
2021-10-28 21:32:25.214 DEBUG 18068 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'org.springframework.aop.config.internalAutoProxyCreator'
2021-10-28 21:32:25.365 DEBUG 18068 --- [onPool-worker-7] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'org.springframework.aop.config.internalAutoProxyCreator'
2021-10-28 21:32:31.737 DEBUG 18068 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'org.springframework.aop.config.internalAutoProxyCreator'
2021-10-28 21:32:31.745 DEBUG 18068 --- [onPool-worker-7] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'org.springframework.aop.config.internalAutoProxyCreator'
2021-10-28 21:32:38.153 DEBUG 18068 --- [onPool-worker-7] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'org.springframework.aop.config.internalAutoProxyCreator'
2021-10-28 21:32:44.212 DEBUG 18068 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'org.springframework.aop.config.internalAutoProxyCreator'

java -jar 只有 3/7 internalAutoProxyCreator 被注册。

$ java -jar target/app-1.0-SNAPSHOT.jar --logging.level.org.springframework=DEBUG |grep internalAutoProxyCreator
2021-10-28 21:39:23.434 DEBUG 1672 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'org.springframework.aop.config.internalAutoProxyCreator'
2021-10-28 21:39:45.387 DEBUG 1672 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'org.springframework.aop.config.internalAutoProxyCreator'
2021-10-28 21:39:52.776 DEBUG 1672 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'org.springframework.aop.config.internalAutoProxyCreator'

我错过了什么吗?这可能是 中的错误还是类加载问题?

PS:我正在升级到最新的 Spring Boot。等待 v. 2.6,我报告的 Spring-Data-Jdbc 中的另一个问题已解决。

问题是我使用的 ForkJoinPool 不会将类加载器从 main 线程(Spring 引导应用程序正在加载)传输到其子线程。切换到 ExecutorService,一切都很好。