Rom*_*kiy 9 java spring dependency-injection java-9
在我的@Configuration课堂上,我有如下的家属:
@Configuration
public class MyConfig {
@Resource(name = "firstDataSource")
private DataSource firstDataSource;
// more code
}
Run Code Online (Sandbox Code Playgroud)
在Oracle JDK 8:firstDataSource字段中工作的依赖项注入已成功注入非null值.
现在我尝试在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
Run Code Online (Sandbox Code Playgroud)
但是在JDK 9下,它会在启动期间抛出异常,这是由以下原因造成的:
Caused by: java.lang.IllegalStateException: bean1 is not injected
at Bean2.<init>(Bean2.java:7)
at Config2.bean2(Config2.java:16)
Run Code Online (Sandbox Code Playgroud)
当没有注入依赖时会发生这种情况.
将java.xml.ws.annotation在jdk9过时的存在可能是你面对什么样的原因.由于注释@Resource来自javax.annotation同一模块导出的包.
您可能希望提供javatm-common-annotations作为可java.xml.ws.annotation导出javax.annotation 的可升级模块.
这个独立版本的Java(TM)Common Annotations使用Java平台模块系统"自动"模块名称java.annotation来匹配JDK 9中使用的模块名称.
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.1</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
使用共享代码在我的机器上运行正常.
此外,还有关于您共享的代码的说明.由于您正在迁移到使用JDK9,因此您应该迁移到使用28-9-2017发布的最新springframework依赖项: -
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.0.RELEASE</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
编辑:请查看 Roman的答案,以便--add-modules在您不打算迁移到已javaee展开的模块的情况下使用.
添加一些缺少的细节.
弹簧@Resource驱动注射仅javax.annotation.Resource在运行时可用时才有效.春天检查:
private static final boolean jsr250Present =
ClassUtils.isPresent("javax.annotation.Resource", AnnotationConfigUtils.class.getClassLoader());
Run Code Online (Sandbox Code Playgroud)
然后使用该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.这使代码保持不变.