2

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

 1 year ago
source link: https://www.v2ex.com/t/883764
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

V2EX  ›  程序员

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

  NoKey · 8 小时 11 分钟前 · 1277 次点击

整体基于 springboot 框架

有一个 bean

@Component
public class DemoParam {
    private int flag;
}

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

我想到的方法有:

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

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

请大家指点,谢谢

17 条回复    2022-09-29 16:15:20 +08:00
bcllemon

bcllemon      8 小时 9 分钟前

用用 @Value 注解,直接配置?
JYii

JYii      8 小时 6 分钟前

实现 ApplicationRunner 方法,@order 自定义顺序
wolfie

wolfie      8 小时 1 分钟前

放在 @PostConstruct 好管理。

---

可以统一放到 @Configuration 里面。

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

---

或者 去掉 @Component ,手动创建 @Bean
yazinnnn

yazinnnn      7 小时 56 分钟前

private val flag by lazy {repo.getFlag()}

能用 kotlin 的话,可以直接 by lazy
NoKey

NoKey      7 小时 51 分钟前

@bcllemon 需要即时从数据库获取
NoKey

NoKey      7 小时 50 分钟前

@JYii 意思是,在 springboot 启动的过程,去给 DemoParam 这个 bean ,set 一个值进去么?谢谢
moshiyeap100

moshiyeap100      7 小时 48 分钟前

2 楼的是一个不错的方法,个人觉得比 @PostConstruct 更适合一点。

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

这两个 Runner 会在容器启动完成后自动执行,而且可以按顺序启动。
zilongzixue

zilongzixue      6 小时 44 分钟前   ❤️ 1

@PostConstruct 就行了,不用搞那么多花里胡哨的东西
nothingistrue

nothingistrue      5 小时 39 分钟前

有一个比较重的方式,如果只是初始化一两个全局变量的话没必要,如果是参与系统架构调整的话,可以考虑。

定义并注册 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

wellerman      5 小时 21 分钟前

既然都放数据库了,肯定还有更改的时候。那参考一下 ruoyi-vue-pro ,把它那个简化后的 apollo client 移植过来,一劳永逸。
dddd1919

dddd1919      4 小时 57 分钟前

如果这种初始化的变量后面会越来越多的话,建议使用懒加载的方式避免服务启动时间越来越长

第一种可以在类里定义属性然后定义 getter 方法,在方法中
```java
if (null == flag) {
flag = 从数据库读取
}
return flag
```
lonenol

lonenol      4 小时 49 分钟前

感觉你这个需求不太对。。如果是配置还是放在配置文件里更好一点。。
这种做法可能需要考虑一下性能和启动速度,如果懒加载了可能需要考虑第一次访问会不会造成拥堵
FanError

FanError      4 小时 39 分钟前

@zilongzixue
@wolfie
放在 ApplicationRunner 里比 PostConstruct 好,如果是微服务下,feign 远程调用可能还没初始化完成。
aptupdate

aptupdate      4 小时 35 分钟前

@lonenol op 的需求是从数据库里获取值,不过也是需要考虑启动速度和拥堵的问题。
如果只有一个参数的话无所谓,参数多的话考虑 Apollo 或者 nacos 这种配置管理组件?
watzds

watzds      4 小时 30 分钟前

读数据库干嘛搞一个变量呢,直接调用方法呗
zliea

zliea      4 小时 5 分钟前

我习惯性用 initializeBean
Chinsung

Chinsung      3 小时 32 分钟前

不如放在配置中心里去,这样只会越写越复杂

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK