jdk17禁止反射,这么说如果严格遵循其规定的话,spring等框架岂不是不能用了?毕竟spring框架就是建立在反射的基础上做的,有没有哪位技术大拿来指教一下
1条回答 默认 最新
关注让【道友老李】来帮你解答,本回答参考通义千问大模型编写,并整理提供,如果还有疑问可以点击头像关注,评论或留言
### 问题解答关于JDK 17禁止反射的说法并不准确。实际上,JDK 17并没有完全禁止反射,而是对某些特定的反射操作进行了限制,特别是那些可能破坏模块化系统安全性的操作。这些限制主要影响的是模块化系统(即使用
module-info.java文件定义的模块)中的类和包。反射限制的具体内容
在JDK 9引入模块系统后,Java平台开始支持更严格的封装和访问控制。具体来说:
- 默认情况下,模块内的包是不可访问的:如果一个包没有被明确地导出(通过
exports指令),那么其他模块或未命名模块(传统JAR文件)将无法通过反射访问该包中的类。 - 强封装:从JDK 16开始,可以通过
--illegal-access=deny选项来完全禁止非法反射访问。这意味着即使在未命名模块中,也无法通过反射访问非公开API。
Spring框架与反射
Spring框架确实大量使用了反射机制来进行依赖注入、AOP等功能。然而,Spring的设计考虑到了这些限制,并且提供了相应的解决方案。
解决方案
- 自动模块:对于传统的JAR文件(未命名模块),它们会被视为自动模块。自动模块会默认导出所有包,因此反射仍然可以正常工作。
- 配置模块信息:如果你的应用程序使用了模块化系统,可以通过在
module-info.java文件中显式导出所需的包,使得Spring框架能够通过反射访问这些包。
示例
假设我们有一个简单的模块化应用程序,其中包含一个名为
com.example.myapp的包,我们希望Spring能够通过反射访问这个包中的类。-
创建模块描述文件:
// module-info.java module com.example.myapp { exports com.example.myapp; // 导出包 requires spring.core; // 声明对Spring Core模块的依赖 } -
确保Spring可以访问: 在
module-info.java中导出必要的包后,Spring框架就可以通过反射访问这些包中的类了。 -
运行时配置: 如果你使用的是JDK 16及以上版本,建议在启动应用程序时添加以下JVM参数,以确保不会因为非法反射访问而出现问题:
--add-opens com.example.myapp/com.example.myapp=ALL-UNNAMED
代码示例
假设我们有一个简单的Spring Boot应用程序,其中包含一个
MyService类:// com/example/myapp/MyService.java package com.example.myapp; public class MyService { public void doSomething() { System.out.println("Doing something..."); } }在
module-info.java中导出该包:// module-info.java module com.example.myapp { exports com.example.myapp; requires spring.boot; requires spring.context; }在Spring Boot的主类中使用
MyService:// com/example/myapp/MyApplication.java package com.example.myapp; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ApplicationContext; @SpringBootApplication public class MyApplication { public static void main(String[] args) { ApplicationContext context = SpringApplication.run(MyApplication.class, args); MyService myService = context.getBean(MyService.class); myService.doSomething(); } }结论
JDK 17并没有完全禁止反射,而是对模块化系统的反射访问进行了限制。Spring框架通过适当的模块配置和运行时参数,仍然可以在模块化环境中正常使用反射。因此,严格遵循JDK 17的规定并不会导致Spring等框架无法使用。
本回答被题主选为最佳回答 , 对您是否有帮助呢?评论 打赏 举报解决 1无用- 默认情况下,模块内的包是不可访问的:如果一个包没有被明确地导出(通过