V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
karottc
V2EX  ›  Java

分享一个 Springboot + GraalVM 对反射的处理方式

  •  
  •   karottc ·
    karottc · 144 天前 · 3661 次点击
    这是一个创建于 144 天前的主题,其中的信息可能已经有所发展或是发生改变。

    GraalVM 官方对反射的出来,要求程序员自己去把所欲需要的类全部写到配置文件,否则运行就会处理失败, 配置文件放在 resource 下面的 reflect-config.json 文件中。

    类多的话,每次都要写一大堆,我用起来感觉非常不方便。

    后面用了 Quarkus ,可以直接用一个注解标识,然后就完全不用写配置文件了,这种只要不是去动老代码,开发过程是非常方便的。

    所以想让 spring 也支持使用一个注解就能搞定反射,而不是去写一堆的配置文件。spring 6.x 本身提供了两个基础注解,但是不能直接支持,需要自己再封装一下就可以了。 把封装代码放下面,非常简单,拷贝即用:

    @Target(AnnotationTarget.CLASS)
    @Retention(AnnotationRetention.RUNTIME)
    @MustBeDocumented
    annotation class ReflectiveClass
    
    @Configuration
    @ImportRuntimeHints(AppRuntimeHintsRegistrar::class)
    class AppConfiguration
    
    class AppRuntimeHintsRegistrar : RuntimeHintsRegistrar {
        override fun registerHints(hints: RuntimeHints, classLoader: ClassLoader?) {
            val scanPackages = listOf("ai.article")
    
            val scanner = ClassPathScanningCandidateComponentProvider(false)
            scanner.addIncludeFilter(AnnotationTypeFilter(ReflectiveClass::class.java))
    
            for (package2Scan in scanPackages) {
                val reflectiveClasses = scanner.findCandidateComponents(package2Scan).map {
                    Class.forName(it.beanClassName, true, classLoader)
                }
                for (className in reflectiveClasses) {
                    hints.reflection().registerType(className,
                        MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
                        MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS,
                        MemberCategory.INVOKE_DECLARED_METHODS,
                        MemberCategory.INVOKE_PUBLIC_METHODS,
                        MemberCategory.DECLARED_FIELDS,
                        MemberCategory.PUBLIC_FIELDS
                    )
                }
            }
        }
    }
    

    现在只需要再需要反射的类上面使用 @ReflectiveClass 就可以了。 不需要其他任何额外的工作。

    5 条回复    2024-08-08 15:30:49 +08:00
    kw8023cn
        1
    kw8023cn  
       143 天前
    没用过,表示点赞学习
    kylix
        2
    kylix  
       143 天前
    感谢分享!有空试试
    CodeCodeStudy
        3
    CodeCodeStudy  
       143 天前
    如果引入了第三方依赖呢,该怎么办?
    karottc
        4
    karottc  
    OP
       143 天前
    @CodeCodeStudy 这个要看具体的情况,比如 gson 这个第三方库,上面的注解就没问题,可以解决。
    codingmiao
        5
    codingmiao  
       135 天前
    我是 java -agentlib:native-image-agent=config-output-dir=META-INF/native-image -jar xxx.jar 先跑起 jar 包来,然后跑测试用例,测完后 reflect-config.json 这些也自动生成出来了,优点是不用去动原来的代码,缺点是测试用例覆盖不全的话可能会出问题。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1654 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 16:35 · PVG 00:35 · LAX 08:35 · JFK 11:35
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.