Spring: @Resource 注入在 JDK9 下停止工作
Spring: @Resource injection stopped working under JDK9
在我的 @Configuration
class 中,我有如下依赖关系:
@Configuration
public class MyConfig {
@Resource(name = "firstDataSource")
private DataSource firstDataSource;
// more code
}
依赖项注入在 Oracle JDK8 中有效:firstDataSource
字段已成功注入非空值。
现在我尝试 运行 JDK 9 中的应用程序(没有修改)。结果是 @Resource
不再触发依赖注入:用这个注释注释的所有内容仍然是 null
.
@Resource
停止工作的原因可能是什么?
Spring项目中使用的是4.0.9
这是一个演示问题的测试项目:https://github.com/rpuch/test-spring-injection-jdk9
它包含一个测试:MainTest
,我 运行 来自我的 IDE。当我使用 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
但是在JDK9下,启动时抛出异常,原因如下:
Caused by: java.lang.IllegalStateException: bean1 is not injected
at Bean2.<init>(Bean2.java:7)
at Config2.bean2(Config2.java:16)
当没有注入依赖项时会发生这种情况。
jdk9 中弃用的 java.xml.ws.annotation
可能是您所面临问题的原因。由于注释 @Resource
来自同一模块导出的包 javax.annotation
。
您可能想要提供 javatm-common-annotations as an upgradeable module for java.xml.ws.annotation
导出 javax.annotation.
This standalone release of Java(TM) Common Annotations uses a Java Platform Module System "automatic" module name of java.annotation, to match the
module name used in JDK 9.
central suggests上的搜索,可以使用:-
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.1</version>
</dependency>
使用您的共享代码,这在我的机器上运行良好。
此外,关于您共享的代码的说明。由于您正在迁移到使用 JDK9,因此您应该迁移到使用最新的 springframework dependencies released as on 28-9-2017:-
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.0.RELEASE</version>
</dependency>
Edit :请查看 以了解如何使用 --add-modules
如果您还不打算迁移到 javaee
展开的模块。
添加一些缺失的细节。
Spring @Resource
驱动的注入仅在 javax.annotation.Resource
在 运行 时间可用时才有效。 Spring 检查:
private static final boolean jsr250Present =
ClassUtils.isPresent("javax.annotation.Resource", AnnotationConfigUtils.class.getClassLoader());
然后使用那个 jsr250Present
变量来查看是否应该启用基于 @Resource
的注入(以及 @PostConstruct
/@PreDestroy
功能)。
就我而言,在 JDK 9 下,此 class 在 运行 时间内不可用,因为它属于一个单独的模块 java.ws.xml.annotation
(与基本模块分开java.base
模块包含 java.lang
和其他一些始终可用的包)。为了解决这个问题,可以采取以下方法之一:
- 按照@AlanBateman 和@nullpointer 的建议,将
javax.annotation-api
库添加到我的应用程序class路径中。
- 作为替代方案,可以指示
java
使用命令行开关添加模块:--add-modules java.xml.ws.annotation
。这使代码完好无损。
在我的 @Configuration
class 中,我有如下依赖关系:
@Configuration
public class MyConfig {
@Resource(name = "firstDataSource")
private DataSource firstDataSource;
// more code
}
依赖项注入在 Oracle JDK8 中有效:firstDataSource
字段已成功注入非空值。
现在我尝试 运行 JDK 9 中的应用程序(没有修改)。结果是 @Resource
不再触发依赖注入:用这个注释注释的所有内容仍然是 null
.
@Resource
停止工作的原因可能是什么?
Spring项目中使用的是4.0.9
这是一个演示问题的测试项目:https://github.com/rpuch/test-spring-injection-jdk9
它包含一个测试:MainTest
,我 运行 来自我的 IDE。当我使用 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
但是在JDK9下,启动时抛出异常,原因如下:
Caused by: java.lang.IllegalStateException: bean1 is not injected
at Bean2.<init>(Bean2.java:7)
at Config2.bean2(Config2.java:16)
当没有注入依赖项时会发生这种情况。
jdk9 中弃用的 java.xml.ws.annotation
可能是您所面临问题的原因。由于注释 @Resource
来自同一模块导出的包 javax.annotation
。
您可能想要提供 javatm-common-annotations as an upgradeable module for java.xml.ws.annotation
导出 javax.annotation.
This standalone release of Java(TM) Common Annotations uses a Java Platform Module System "automatic" module name of java.annotation, to match the module name used in JDK 9.
central suggests上的搜索,可以使用:-
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.1</version>
</dependency>
使用您的共享代码,这在我的机器上运行良好。
此外,关于您共享的代码的说明。由于您正在迁移到使用 JDK9,因此您应该迁移到使用最新的 springframework dependencies released as on 28-9-2017:-
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.0.RELEASE</version>
</dependency>
Edit :请查看 --add-modules
如果您还不打算迁移到 javaee
展开的模块。
添加一些缺失的细节。
Spring @Resource
驱动的注入仅在 javax.annotation.Resource
在 运行 时间可用时才有效。 Spring 检查:
private static final boolean jsr250Present =
ClassUtils.isPresent("javax.annotation.Resource", AnnotationConfigUtils.class.getClassLoader());
然后使用那个 jsr250Present
变量来查看是否应该启用基于 @Resource
的注入(以及 @PostConstruct
/@PreDestroy
功能)。
就我而言,在 JDK 9 下,此 class 在 运行 时间内不可用,因为它属于一个单独的模块 java.ws.xml.annotation
(与基本模块分开java.base
模块包含 java.lang
和其他一些始终可用的包)。为了解决这个问题,可以采取以下方法之一:
- 按照@AlanBateman 和@nullpointer 的建议,将
javax.annotation-api
库添加到我的应用程序class路径中。 - 作为替代方案,可以指示
java
使用命令行开关添加模块:--add-modules java.xml.ws.annotation
。这使代码完好无损。