SpringBean的静态字段/静态属性(static的field),支持Apollo配置热更新吗?
<p>我们知道,springbean的静态field可以通过显式的setter方法(实例方法)实现注入。</p><p><code>下面LaborFeeCalculator</code>,其中的 <code>basePercentage</code> 是一个静态field。通过显式<code>@Value</code>的<code>setter</code>方法来进行配置参数赋值。</p>
<table class="wysiwyg-macro" style="background-image: url("http://wiki.serviceshare.com/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGU6bGFuZ3VhZ2U9amF2YX0&locale=zh_CN&version=2"); background-repeat: no-repeat" data-macro-name="code" data-macro-id="260290a1-6a90-4b50-a5d1-88f1c4395092" data-macro-parameters="language=java" data-macro-schema-version="1" data-macro-body-type="PLAIN_TEXT">
<tbody>
<tr>
<td class="wysiwyg-macro-body">
<pre class="highlighter-hljs"><code>@Component
public class LaborFeeCalculator {
private static FeeRate basePercentage;
@Value("${bossKg.order-base-percentage:80}")
public void setBasePercentage(BigDecimal value) {
basePercentage = FeeRate.PERCENTAGE.of(value);
}
...
}</code></pre>
</td>
</tr>
</tbody>
</table>
<p> </p>
<p>问题:当apollo里的配置项”<code>bossKg.order-base-percentage</code>“的值发生变更时,static变量<code>basePercentage</code>的值会跟着变化吗? 也就是说,静态属性(static field)支持配置热更新吗?</p>
<p> </p>
<p>我认为是可以的。因为这与field是否静态无关,而与 @Value修饰的setter方法有关。当配置值变更时,这个setter方法就会触发执行。 </p>
<p>好奇的我,想看看apollo的相关日志。所以,亲测一下。</p>
<p> </p>
<p> </p>
<p>下面是测试代码。由后面的执行日志可以看出来,这3种使用<code>@Value</code>的方式,都可以实现配置热更。</p>
<table class="wysiwyg-macro" style="background-image: url("http://wiki.serviceshare.com/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGU6bGFuZ3VhZ2U9amF2YXx0aGVtZT1FbWFjc30&locale=zh_CN&version=2"); background-repeat: no-repeat" data-macro-name="code" data-macro-id="7ef0cf3a-ad81-4794-bbe1-57c69b3dba3d" data-macro-parameters="language=java|theme=Emacs" data-macro-schema-version="1" data-macro-body-type="PLAIN_TEXT">
<tbody>
<tr>
<td class="wysiwyg-macro-body">
<pre class="highlighter-hljs"><code>package com.emaxcard.boss.modules.usertaxmonthlytotal;
import com.emax.trans.FeeRate;
import com.emaxcard.boss.ServerApplication;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.math.BigDecimal;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = ServerApplication.class)
@Slf4j
class LaborFeeCalculatorTest {
private FeeRate basePercentage;
@Value("${bossKg.order-base-percentage:10}")
public void setBasePercentage(BigDecimal value) {
basePercentage = FeeRate.PERCENTAGE.of(value);
log.info("LaborFeeCalculatorTest.order-base-percentage:{}", basePercentage);
}
private static FeeRate basePercentage2;
@Value("${bossKg.order-base-percentage:10}")
public void setBasePercentage2(BigDecimal value) {
basePercentage2 = FeeRate.PERCENTAGE.of(value);
log.info("LaborFeeCalculatorTest.order-base-percentage:{}", basePercentage2);
}
@Value("${bossKg.order-base-percentage:10}")
private String orderBasePercentage;
@Test
public void testCalculate() throws InterruptedException {
for (int i = 0; i < 500; i++) {
System.out.println("loop"+i + ":" + basePercentage + "++++++++++++++++" + basePercentage2 + "++++++++++++++++" + orderBasePercentage);
Thread.sleep(1000);
}
}
}</code></pre>
</td>
</tr>
</tbody>
</table>
<p> </p>
<p>下面是执行test的日志:</p>
<table class="wysiwyg-macro" style="background-image: url("http://wiki.serviceshare.com/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGU6bGFuZ3VhZ2U9amF2YX0&locale=zh_CN&version=2"); background-repeat: no-repeat" data-macro-name="code" data-macro-id="8340f4c1-dc51-41f0-95b6-f532aebf9797" data-macro-parameters="language=java" data-macro-schema-version="1" data-macro-body-type="PLAIN_TEXT">
<tbody>
<tr>
<td class="wysiwyg-macro-body">
<pre class="language-less highlighter-hljs"><code>loop0:0.77++++++++++++++++0.77++++++++++++++++77
loop1:0.77++++++++++++++++0.77++++++++++++++++77
loop2:0.77++++++++++++++++0.77++++++++++++++++77
loop3:0.77++++++++++++++++0.77++++++++++++++++77
loop4:0.77++++++++++++++++0.77++++++++++++++++77
// 【【【这时,在apollo控制台修改&发布了property的值 77→93】】】
// 项目中的 LaborFeeCalculator.setBasePercentage 感知到变化
12:53:56.891 INFOc.c.f.a.s.property.AutoUpdateConfigChangeListener:? - Auto update apollo changed value successfully, new value: 93, key: bossKg.order-base-percentage, beanName: laborFeeCalculator, method: com.emaxcard.boss.modules.usertaxmonthlytotal.LaborFeeCalculator.setBasePercentage
// 当前test类 LaborFeeCalculatorTest.orderBasePercentage 感知到变化
12:53:56.891 INFOc.c.f.a.s.property.AutoUpdateConfigChangeListener:? - Auto update apollo changed value successfully, new value: 93, key: bossKg.order-base-percentage, beanName: com.emaxcard.boss.modules.usertaxmonthlytotal.LaborFeeCalculatorTest.ORIGINAL, field: com.emaxcard.boss.modules.usertaxmonthlytotal.LaborFeeCalculatorTest.orderBasePercentage
// 当前test类 LaborFeeCalculatorTest.setBasePercentage 感知到变化
12:53:56.891 INFOc.c.f.a.s.property.AutoUpdateConfigChangeListener:? - Auto update apollo changed value successfully, new value: 93, key: bossKg.order-base-percentage, beanName: com.emaxcard.boss.modules.usertaxmonthlytotal.LaborFeeCalculatorTest.ORIGINAL, method: com.emaxcard.boss.modules.usertaxmonthlytotal.LaborFeeCalculatorTest.setBasePercentage
// 当前test类 LaborFeeCalculatorTest.setBasePercentage2 感知到变化
12:53:56.891 INFOc.c.f.a.s.property.AutoUpdateConfigChangeListener:71 - Auto update apollo changed value successfully, new value: 93, key: bossKg.order-base-percentage, beanName: com.emaxcard.boss.modules.usertaxmonthlytotal.LaborFeeCalculatorTest.ORIGINAL, method: com.emaxcard.boss.modules.usertaxmonthlytotal.LaborFeeCalculatorTest.setBasePercentage2
loop5:0.93++++++++++++++++0.93++++++++++++++++93
loop6:0.93++++++++++++++++0.93++++++++++++++++93
...</code></pre>
</td>
</tr>
</tbody>
</table>
<p> </p>
<p data-tool="mdnice编辑器">在日志中可以看到,Apollo分别更新了:</p>
<ul data-tool="mdnice编辑器">
<li><code>LaborFeeCalculator.setBasePercentage</code>(静态字段的setter)</li>
<li><code>LaborFeeCalculatorTest.orderBasePercentage</code>(实例字段)</li>
<li><code>LaborFeeCalculatorTest.setBasePercentage</code>(实例字段的setter)</li>
<li><code>LaborFeeCalculatorTest.setBasePercentage2</code>(静态字段的setter)</li>
</ul>
<h3 data-tool="mdnice编辑器"><span class="content">结论</span></h3>
<ul data-tool="mdnice编辑器">
<li><strong>静态字段支持热更新</strong>:在Apollo的扩展支持下,即使是静态字段,只要通过<code>@Value</code>注解并提供了setter方法,Apollo在配置变更时会主动调用该setter方法,从而更新静态字段的值。</li>
</ul>
</div>
<div id="MySignature" role="contentinfo">
<hr class="signhr"><p style="text-indent:2em;font-size:12px;text-align:center">当看到一些不好的代码时,会发现我还算优秀;当看到优秀的代码时,也才意识到持续学习的重要!--buguge<br>本文来自博客园,转载请注明原文链接:https://www.cnblogs.com/buguge/p/18979785</p><hr class="signhr">
<style>hr.signhr{width:80%;margin:0 auto;border: 0;height: 4px;background-image: linear-gradient(to right, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.75), rgba(0, 0, 0, 0))}</style><br><br>
来源:https://www.cnblogs.com/buguge/p/18979785
頁:
[1]