使用 @Async 在 Weblogic 部署中自动装配 Spring 和 bean 范围:NullPointerException

问题描述

考虑具有以下(简化)架构的 Spring Web 应用程序:

  1. 带有@Async 注释的方法的服务:
@Service
public class MatriceAsyncFacade implements IMatriceAsyncFacade {

    @Resource
    private MatriceService myService;

    @Override
    @Async(MatriceFacadeAsyncConfig.MATRICE_EXECUTOR_NAME )
    public Future<MyClass> getMatriceFuture(Matrice matrice) throws TaskRejectedException {
            return new AsyncResult<>(this.myService.build(matrice));
    }
}

  1. 一个配置类:
@Configuration
@EnableAsync
public class MatriceFacadeAsyncConfig {

    public static final String MATRICE_EXECUTOR_NAME = "builderMatriceExecutor";

    @Resource
    private InitialisationDto initialisationDto;

    @Bean(name = MATRICE_EXECUTOR_NAME)
    // @Scope(WebApplicationContext.ScopE_APPLICATION) // IMPORTANT_LINE_1
    public Executor threadPoolTaskExecutor() {
        final ThreadPoolTaskExecutor tpte = new ThreadPoolTaskExecutor();

        LOGGER.info("threadPoolTaskExecutor() corePoolSize={}",this.initialisationDto.getMatriceExecutorCorePoolSize());

        tpte.setCorePoolSize(this.initialisationDto.getMatriceExecutorCorePoolSize());

        return tpte;
    }
}
  1. 一个配置 bean (InitialisationDto),在 application-context.xml 中声明并首先由 Spring 实例化
  <bean id="initialisationDto" class="com.my.package.initialisation.InitialisationDto">
    <property name="matriceExecutorCorePoolSize" value="${matrice.executor.core.pool.size}" />
  </bean>

问题是:

  • 在(本地)Tomcat 中部署 web 应用程序,它工作正常(注意注释的 @Scope() )

  • 在我们的集成 Weblogic 服务器中部署 web 应用程序,我必须添加 @Scope 行,否则我在部署时会出现 NullPointerException

Caused By: java.lang.NullPointerException
        at com.my.pacakge.config.MatriceFacadeAsyncConfig.threadPoolTaskExecutor(MatriceFacadeAsyncConfig.java:48)
        at com.my.pacakge.config.MatriceFacadeAsyncConfig$$EnhancerBySpringcglib$$615d2556.cglib$threadPoolTaskExecutor$0(<generated>)

NPE 是从这一行提出的:

tpte.setCorePoolSize(this.initialisationDto.getMatriceExecutorCorePoolSize());

在日志中,我可以首先看到 webapp 被初始化,InitialisationDto 被实例化和填充。紧接着,ConfigurationClass 中的 bean 被创建并显示日志“corePoolSize=...”。 在那之后我有 NPE,好像 Weblogic 试图再次实例化这个 bean,但没有 InitialisationDto 可用。

认情况下,bean 是单例,那么为什么在执行程序 bean 上添加 @Scope(WebApplicationContext.ScopE_APPLICATION) 似乎可以解决问题?

注意:添加 Scope 注解时,Executor 似乎被懒惰地实例化,而不是在应用程序部署时。

版本:

  • Java 8
  • Spring 4.3.9.RELEASE
  • Weblogic 12.2
  • 雄猫 9

TLDR:@Async [singleton vs APPLICATION_ScopE] bean 在 Weblogic 部署中的实际差异?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)