建筑转Java-张无忌 2024-12-17 11:46 采纳率: 75%
浏览 53
已结题

jdk17禁止反射,这么说如果严格遵循其规定的话,spring等框架岂不是不能用了?

jdk17禁止反射,这么说如果严格遵循其规定的话,spring等框架岂不是不能用了?毕竟spring框架就是建立在反射的基础上做的,有没有哪位技术大拿来指教一下

  • 写回答

1条回答 默认 最新

  • 道友老李 JWE233286一种基于机器视觉的水表指针读数识别及修正的方法 专利发明者 2024-12-17 12:01
    关注
    让【道友老李】来帮你解答,本回答参考通义千问大模型编写,并整理提供,如果还有疑问可以点击头像关注,评论或留言
    ### 问题解答

    关于JDK 17禁止反射的说法并不准确。实际上,JDK 17并没有完全禁止反射,而是对某些特定的反射操作进行了限制,特别是那些可能破坏模块化系统安全性的操作。这些限制主要影响的是模块化系统(即使用module-info.java文件定义的模块)中的类和包。

    反射限制的具体内容

    在JDK 9引入模块系统后,Java平台开始支持更严格的封装和访问控制。具体来说:

    1. 默认情况下,模块内的包是不可访问的:如果一个包没有被明确地导出(通过exports指令),那么其他模块或未命名模块(传统JAR文件)将无法通过反射访问该包中的类。
    2. 强封装:从JDK 16开始,可以通过--illegal-access=deny选项来完全禁止非法反射访问。这意味着即使在未命名模块中,也无法通过反射访问非公开API。

    Spring框架与反射

    Spring框架确实大量使用了反射机制来进行依赖注入、AOP等功能。然而,Spring的设计考虑到了这些限制,并且提供了相应的解决方案。

    解决方案

    1. 自动模块:对于传统的JAR文件(未命名模块),它们会被视为自动模块。自动模块会默认导出所有包,因此反射仍然可以正常工作。
    2. 配置模块信息:如果你的应用程序使用了模块化系统,可以通过在module-info.java文件中显式导出所需的包,使得Spring框架能够通过反射访问这些包。

    示例

    假设我们有一个简单的模块化应用程序,其中包含一个名为com.example.myapp的包,我们希望Spring能够通过反射访问这个包中的类。

    1. 创建模块描述文件

      // module-info.java
      module com.example.myapp {
         exports com.example.myapp;  // 导出包
         requires spring.core;       // 声明对Spring Core模块的依赖
      }
      
    2. 确保Spring可以访问: 在module-info.java中导出必要的包后,Spring框架就可以通过反射访问这些包中的类了。

    3. 运行时配置: 如果你使用的是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等框架无法使用。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 12月25日
  • 已采纳回答 12月17日
  • 创建了问题 12月17日