Spring:@Resource注入在JDK9下停止工作

在我的@Configuration类中,我有如下的dependendies:

 @Configuration public class MyConfig { @Resource(name = "firstDataSource") private DataSource firstDataSource; // more code } 

dependency injection在Oracle JDK 8中工作: firstDataSource字段已成功注入非null值。

现在我尝试在JDK 9中运行应用程序(没有修改)。结果是@Resource不再触发dependency injection:使用此批注注释的所有内容都保持为null

@Resource停止工作的原因是什么?

Spring 4.0.9用于项目中。

这是一个展示问题的测试项目: https : //github.com/rpuch/test-spring-injection-jdk9

它包含一个测试:我从IDE运行的MainTest 。 当我使用JDK 8时,它会输出

 сен 29, 2017 10:45:13 PM org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh INFO: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@5f8ed237: startup date [Fri Sep 29 22:45:13 SAMT 2017]; root of context hierarchy OK 

但是在JDK 9下,它会在启动期间抛出exception,这是由以下原因引起的:

 Caused by: java.lang.IllegalStateException: bean1 is not injected at Bean2.(Bean2.java:7) at Config2.bean2(Config2.java:16) 

当没有注入依赖时会发生这种情况。

在jdk9中不推荐使用的java.xml.ws.annotation可能是您所面临的原因。 由于注释@Resource来自同一模块导出的包javax.annotation

您可能希望提供javatm-common-annotations作为java.xml.ws.annotation的可升级模块,该模块导出javax.annotation。

这个独立版本的Java(TM)Common Annotations使用Java平台模块系统“自动”模块名称java.annotation来匹配JDK 9中使用的模块名称。

对中心的搜索表明 ,您可以使用: –

  javax.annotation javax.annotation-api 1.3.1  

使用共享代码在我的机器上运行正常。


另外,关于您共享的代码的说明。 由于您正在迁移到使用JDK9,因此您应该迁移到使用28-9-2017发布的最新springframework依赖项 : –

  org.springframework spring-context 5.0.0.RELEASE  

编辑 :请查看Roman的答案 ,以便在您不打算迁移到javaee探索模块的情况下使用--add-modules

添加一些缺少的细节。

Spring @Resource -driven注入仅在运行时javax.annotation.Resource可用时才有效。 Spring检查:

 private static final boolean jsr250Present = ClassUtils.isPresent("javax.annotation.Resource", AnnotationConfigUtils.class.getClassLoader()); 

然后使用该jsr250Present变量来查看是否应启用基于@Resource的注入(以及@PostConstruct / @PreDestroyfunction)。

在我的例子中,在JDK 9下,这个类在运行时不可用,因为它属于一个单独的模块java.ws.xml.annotation (与包含java.lang的基本java.base模块和其他一些总是不同的包分开)可用)。 要解决该问题,可以采取以下方法之一:

  1. javax.annotation-api库添加到我的应用程序类路径中,如@AlanBateman和@nullpointer建议的那样。
  2. 作为替代方案,可以指示java使用命令行开关添加模块: – --add-modules java.xml.ws.annotation 。 这使代码完好无损。