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

新手请教, springboot 框架下,哪种初始化变量的方法更好

  •  
  •   NoKey · 2022-09-29 11:36:53 +08:00 · 3014 次点击
    这是一个创建于 788 天前的主题,其中的信息可能已经有所发展或是发生改变。

    整体基于 springboot 框架

    有一个 bean

    @Component
    public class DemoParam {
        private int flag;
    }
    

    flag需要在初始化阶段从数据库获取值

    我想到的方法有:

    • 在构造方法中初始化 flag
    • 写一个方法,用@PostConstruct注解

    哪种方法更好呢,或者有没有更好、更优雅的方法

    请大家指点,谢谢

    20 条回复    2022-09-30 14:30:32 +08:00
    bcllemon
        1
    bcllemon  
       2022-09-29 11:38:42 +08:00
    用用 @Value 注解,直接配置?
    JYii
        2
    JYii  
       2022-09-29 11:42:00 +08:00
    实现 ApplicationRunner 方法,@order 自定义顺序
    wolfie
        3
    wolfie  
       2022-09-29 11:47:15 +08:00
    放在 @PostConstruct 好管理。

    ---

    可以统一放到 @Configuration 里面。

    @Bean
    public SmartInitializingSingleton fooBarConfig(@Autowired DemoParam demoParam, @Autowired FooBarMapper fooBarMapper) {
    return () -> {
    demoParam.setFlag(fooBarMapper.getConfig());
    };
    }

    ---

    或者 去掉 @Component ,手动创建 @Bean
    yazinnnn
        4
    yazinnnn  
       2022-09-29 11:51:48 +08:00
    private val flag by lazy {repo.getFlag()}

    能用 kotlin 的话,可以直接 by lazy
    NoKey
        5
    NoKey  
    OP
       2022-09-29 11:56:34 +08:00
    @bcllemon 需要即时从数据库获取
    NoKey
        6
    NoKey  
    OP
       2022-09-29 11:58:09 +08:00
    @JYii 意思是,在 springboot 启动的过程,去给 DemoParam 这个 bean ,set 一个值进去么?谢谢
    moshiyeap100
        7
    moshiyeap100  
       2022-09-29 11:59:28 +08:00
    2 楼的是一个不错的方法,个人觉得比 @PostConstruct 更适合一点。

    可以自行实现 CommandLineRunner 或者 ApplicationRunner ,集中初始化一些需要读库的配置对象。

    这两个 Runner 会在容器启动完成后自动执行,而且可以按顺序启动。
    zilongzixue
        8
    zilongzixue  
       2022-09-29 13:03:40 +08:00   ❤️ 1
    @PostConstruct 就行了,不用搞那么多花里胡哨的东西
    nothingistrue
        9
    nothingistrue  
       2022-09-29 14:08:47 +08:00
    有一个比较重的方式,如果只是初始化一两个全局变量的话没必要,如果是参与系统架构调整的话,可以考虑。

    定义并注册 Spring 容器启动事件监听,再监听中处理,可以一个监听处理多个场景的初始化。
    定义监听类:public class ApplicationContextRefreshed implements ApplicationListener<ContextRefreshedEvent>
    注册监听:启动类修改成如下,
    public static void main(String[] args) {
    SpringApplication springApplication = new SpringApplication(Application.class);
    springApplication.addListeners(new ApplicationContextRefreshed());
    springApplication.run(args);
    }



    还有一种更简单的配置方式,定义下面这个构造器即可:
    @Autowird
    public DemoParam(@Autowird DaoOrJpaRepistory daoOrRepo ){
    flag = daoOrRepo.xxxx;
    }
    wellerman
        10
    wellerman  
       2022-09-29 14:26:58 +08:00
    既然都放数据库了,肯定还有更改的时候。那参考一下 ruoyi-vue-pro ,把它那个简化后的 apollo client 移植过来,一劳永逸。
    dddd1919
        11
    dddd1919  
       2022-09-29 14:50:38 +08:00
    如果这种初始化的变量后面会越来越多的话,建议使用懒加载的方式避免服务启动时间越来越长

    第一种可以在类里定义属性然后定义 getter 方法,在方法中
    ```java
    if (null == flag) {
    flag = 从数据库读取
    }
    return flag
    ```
    lonenol
        12
    lonenol  
       2022-09-29 14:58:18 +08:00
    感觉你这个需求不太对。。如果是配置还是放在配置文件里更好一点。。
    这种做法可能需要考虑一下性能和启动速度,如果懒加载了可能需要考虑第一次访问会不会造成拥堵
    FanError
        13
    FanError  
       2022-09-29 15:08:50 +08:00
    @zilongzixue
    @wolfie
    放在 ApplicationRunner 里比 PostConstruct 好,如果是微服务下,feign 远程调用可能还没初始化完成。
    aptupdate
        14
    aptupdate  
       2022-09-29 15:12:53 +08:00
    @lonenol op 的需求是从数据库里获取值,不过也是需要考虑启动速度和拥堵的问题。
    如果只有一个参数的话无所谓,参数多的话考虑 Apollo 或者 nacos 这种配置管理组件?
    watzds
        15
    watzds  
       2022-09-29 15:18:00 +08:00
    读数据库干嘛搞一个变量呢,直接调用方法呗
    zliea
        16
    zliea  
       2022-09-29 15:42:49 +08:00
    我习惯性用 initializeBean
    Chinsung
        17
    Chinsung  
       2022-09-29 16:15:20 +08:00
    不如放在配置中心里去,这样只会越写越复杂
    voydomnvd
        18
    voydomnvd  
       2022-09-29 20:11:18 +08:00 via Android
    首先单体应用用 ApplicationRunner 就行
    如果是微服务的情况下,配置中心里好一点,有值需要变动的话再加上 @RefreshScope 呗,要是经常变就 Redis 或 DB 了
    fuxinya
        19
    fuxinya  
       2022-09-29 20:14:28 +08:00 via Android
    CommandLineRunner
    vishun
        20
    vishun  
       2022-09-30 14:30:32 +08:00
    如果是只初始化一下的话,放数据库或配置文件都没什么影响。
    但放到数据库更多的是会修改,此时就会涉及到线程安全问题或者是 bean 的热更新问题。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5404 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 03:50 · PVG 11:50 · LAX 19:50 · JFK 22:50
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.