在我的@Configuration
课程中,我有以下内容:
@Configuration
public class MyConfig {
@Resource(name = "firstDataSource")
private DataSource firstDataSource;
// more code
}
在Oracle JDK 8中使用依赖注入: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
但是在JDK 9下,它会在启动期间抛出异常,这是由以下原因引起的:
Caused by: java.lang.IllegalStateException: bean1 is not injected
at Bean2.<init>(Bean2.java:7)
at Config2.bean2(Config2.java:16)
在未注入依赖项时发生。
答案 0 :(得分:7)
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中使用的模块名称。
在central suggests上搜索,您可以使用: -
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.1</version>
</dependency>
使用共享代码在我的计算机上运行正常。
此外,还有关于您共享的代码的说明。由于您要迁移到使用JDK9,因此您应该迁移到使用最新的springframework依赖项released as on 28-9-2017: -
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.0.RELEASE</version>
</dependency>
修改 :如果您不打算迁移到--add-modules
,请查看Roman's answer以便使用javaee
{{1}}已展开的模块。
答案 1 :(得分:6)
添加一些缺失的细节。
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下,此类在运行时不可用,因为它属于单独的模块java.ws.xml.annotation
(与包含java.base
的基本java.lang
模块分开其他总是可用的包。要解决该问题,可以采取以下方法之一:
javax.annotation-api
库添加到我的应用程序类路径中,如@AlanBateman和@nullpointer建议的那样。java
使用命令行开关添加模块:--add-modules java.xml.ws.annotation
。这使代码保持不变。