关于 Java 类加载和 Springboot Bean 动态加载的一点想法 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
EscYezi
V2EX    Java

关于 Java 类加载和 Springboot Bean 动态加载的一点想法

  •  
  •   EscYezi
    yeziyezi 2021-08-07 15:54:57 +08:00 3575 次点击
    这是一个创建于 1555 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近遇到一个情况,需要修改数据库里的一些数据,这些数据是用 json 形式保存的,要给某些 key 对应的 value+1.如果用 sql 写会很复杂,如果能用 java 写好程序触发一下拿到结果就好了,但是这样做要发布到正式环境,调试也是非常不方便,每次发布要等好久。

    于是想到用户 java 的自定义类加载器和 springboot 的 bean 动态加载结合起来,提供一个页面,在本地写好代码,copy 到页面上,点击运行就可以生效。有复杂的导出表格需求也可以实现。(明明当初做管理端的时候弄了那么多数据统计功能,结果还是不能满足业务线的需求)

    大概流程是:点击运行后,把输入的代码变成文件流喂给类加载器,加载新定义的类,然后再加载到 spring 的 bean 容器里面,触发一下这个 bean 的运行,拿到结果返回给页面(有点像在线面试题的感觉)。

    具体细节感觉还是有很多优化的点,想问下有没有类似的现成的工具?最好能和 springboot 结合起来,毕竟复杂逻辑还是要依靠已存在的一些 bean 。(如果没有的话就尝试糊一个好了 2333 )

    20 条回复    2021-08-13 11:41:39 +08:00
    crclz
        1
    crclz  
       2021-08-07 16:17:35 +08:00
    你用这么 hack 的东西,还不如把正式环境暴露给你的开发机呢。
    Cbdy
        2
    Cbdy  
       2021-08-07 16:17:37 +08:00   1
    不用这么麻烦,你可以直接在服务端解释执行一些代码,JVM 上本身就支持一些脚本语言(甚至是 Java ),

    可以看这个例子:
    https://github.com/cbdyzj/lib17/blob/master/repositories/boot/src/main/java/org/jianzhao/boot/service/ScriptService.java

    当然,你也可以动态加载类去做,比如用 java.net.URLClassLoader
    857681664
        3
    857681664  
       2021-08-07 16:29:23 +08:00 via Android
    用 mysql 的 json 函数会非常复杂吗,我都是用 sql 迁移 json 字段的
    scYezi
        4
    EscYezi  
    OP
       2021-08-07 16:40:05 +08:00
    @crclz 我倒是想直连正式环境,但是不太可能
    EscYezi
        5
    EscYezi  
    OP
       2021-08-07 16:42:17 +08:00
    @857681664 公司用的 mysql 版本有点低,不支持 json 类型字段
    EscYezi
        6
    EscYezi  
    OP
       2021-08-07 16:45:05 +08:00
    @Cbdy 直接能写脚本那就更好了,我研究研究
    857681664
        7
    857681664  
       2021-08-07 16:45:39 +08:00 via Android
    @EscYezi 那我觉得你可以通过网络或者文件的方式的方式用类加载器加载 class
    cp19890714
        8
    cp19890714  
       2021-08-07 16:48:23 +08:00 via Android
    完全不是新鲜玩意,tomcat 动态加载 war 包。
    或者用 js,java 自带 js 引擎。
    Suddoo
        9
    Suddoo  
       2021-08-07 18:53:43 +08:00
    MySQL 5.7 就支持 JSON 操作了,比这还低?
    jorneyr
        10
    jorneyr  
       2021-08-07 22:21:11 +08:00
    Spring 里面调用 groovy 做这些也可以,groovy 兼容 Java 。
    lonenol
        11
    lonenol  
       2021-08-07 22:34:58 +08:00
    功能很简单。。直接用 java 代码,也能编译成 class 文件,然后去执行都行。。
    不过最好不要这么做,太容易出问题。。万一没兜住,给线上表来了个全量更新啥的,哭都没地方哭/div>
    securityCoding
        12
    securityCoding  
       2021-08-08 13:30:13 +08:00 via Android
    这样,你搭建一个分布式调度平台,比如 xxl-job 。大部分都提供了动态运行代码功能。
    ljzxloaf
        13
    ljzxloaf  
       2021-08-08 15:02:47 +08:00   1
    动态加载 class 不是什么难事,但是你这样不是等于直接上生产调试?理论上你可以把所以的业务逻辑都弄成动态的,问题是必要性在哪? OSGI 发展这么久为什么被 JPMS 干掉了,因为它所谓的热部署 /热替换根本没啥必要。Web 服务都是集群,无损上下线简单得很,要啥热部署 /热替换。

    “但是这样做要发布到正式环境,调试也是非常不方便,每次发布要等好久” 这是啥理由,造点数据调试不就行了。

    如果只是偶尔手动修改数据,直接用 sql 。如果经常需要手动修改数据,那应该反思的是,为啥要手动修改数据,用户的数据我们没有权限修改,除非是 bug 。
    ljzxloaf
        14
    ljzxloaf  
       2021-08-08 15:07:30 +08:00   1
    @ljzxloaf #13 正常的业务需求走开发测试部署流程,不正常的需求也尽量走正常流程,除非你 100%能 hold 住。你这么玩是否定了测试的价值。
    EscYezi
        15
    EscYezi  
    OP
       2021-08-09 14:59:35 +08:00 via iPhone
    @ljzxloaf 有道理,这个东西放在公司项目上用确实有风险,还是自己研究着玩玩吧
    fengpan567
        16
    fengpan567  
       2021-08-10 18:05:32 +08:00
    生产环境这么玩铁定会出事故
    hcen1997
        17
    hcen1997  
       2021-08-12 11:29:04 +08:00
    生产环境暴露动态代码加载过不去安全检查吧?
    这个需求就是普通的更改数据嘛, 不过数据不是简单的一个字段, 而是字段->json-> 字段的形式

    那只需要在 dao 层加入一个 json 地址解析就行了啊
    +1 需求的功能接口加一个字段 : jsonPath
    对于上层应用还是调用 字段加 1 的函数
    但是对于 dao 层, 先获取 json 字符串, 解析, 根据 jsonPath 更新数据, 转回 json 字符串, -> 存回数据库

    我觉得分层抽象的原理用在这个需求上刚刚好
    EscYezi
        18
    EscYezi  
    OP
       221-08-12 12:20:41 +08:00 via iPhone
    @hcen1997 这也是个思路,不过为什么不直接传递 json 而要传递 json 地址呢
    hcen1997
        19
    hcen1997  
       2021-08-12 13:20:07 +08:00
    @EscYezi json 地址是指 对象中字段的地址
    比如 数据库中存了 '{"t1":{"t2":1}}'
    那么 json 地址就是 t1.t2
    调用完函数后, 数据库中的值就会变成
    '{"t1":{"t2":2}}'

    为啥不直接传递 json? 随意啊, 想怎么写怎么写,
    aguesuka
        20
    aguesuka  
       2021-08-13 11:41:39 +08:00
    osgi 是编程语言发展的弯路, 不要开倒车
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3341 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 00:07 PVG 08:07 LAX 16:07 JFK 19:07
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86