类似于nacos的动态配置,但是又不完全是,起初是因为一部分朋友不知道怎么去配静态配置(application.properties)和方便使用docker去运行而存在的。
当我们使用 getter 去获取数据时,一般是使用 getXxx这样的方法来获取,这是java全球通用的约定。然后我们使用动态配置时,我们使用一个切面去代理这个方法。
切点:
@Pointcut("@within(com.dobbinsoft.fw.support.annotation.DynamicConfigProperties)")
走代理方法,
@Around("cachePointCut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
MethodSignature signature = (MethodSignature)joinPoint.getSignature();
DynamicConfigProperties annotation = (DynamicConfigProperties)signature.getDeclaringType().getAnnotation(DynamicConfigProperties.class);
if (annotation != null) {
String prefix = annotation.prefix();
// 去对应的分组读取配置
Class returnType = signature.getReturnType();
if (returnType == String.class) {
return dynamicConfigComponent.readString(prefix + ReflectUtil.getField(signature.getName()), null);
} else if (returnType == Integer.class) {
return dynamicConfigComponent.readInt(prefix + ReflectUtil.getField(signature.getName()), null);
} else if (returnType == Long.class) {
return dynamicConfigComponent.readLong(prefix + ReflectUtil.getField(signature.getName()), null);
} else if (returnType == Boolean.class) {
return dynamicConfigComponent.readBoolean(prefix + ReflectUtil.getField(signature.getName()), null);
}
}
return joinPoint.proceed();
}
所以根本没用对象里面的属性,只用了它的方法签名,所以**请不要在群里面问,为什么对象里面没数据,又能get出来了.**
动态配置,只提供了一个持久化策略的接口,默认support包中给出 DynamicStorageFileSystemStrategy、DynamicStoragePropertiesStrategy 分别为文件系统持久化、静态配置文件持久化策略。这两个建议都不要用,文件系统持久化,将会破坏服务“无状态”的特性,不符合容器化的核心价值观。静态配置持久化则完全是为了测试时方便。当然在dobbinfw脚手架项目中给出了默认的mysql持久化策略。
public interface DynamicStorageStrategy {
/**
* 覆盖写,若存在,则更新,若不存在则写
* @param key
* @param value
*/
public void write(String key, String value);
public String read(String key);
public boolean del(String key);
}
Q: 为什么mysql持久化策略要放在脚手架中?
A: 因为动态配置support包认为是一个可有可无的东西。业务系统也许不会用。
@EnableDynamicConfig
public class PromallApplication {
// 在启动类上注解上,开启动态配置的注解
}
@Data
@DynamicConfigProperties(prefix = DynamicConst.ADVERT_CONFIG_PREFIX)
public class UnimallAdvertProperties {
/**
* 首页TOP N 个数
*/
private Integer topSalesNum;
}
@Autowired
private UnimallAdvertProperties unimallAdvertProperties;
....
Integer topSalesNum = unimallAdvertProperties.getTopSalesNum();
@Autowired
private DynamicConfigComponent dynamicConfigComponent;
....
// prefix与上文DynamicConst.ADVERT_CONFIG_PREFIX对应,
dynamicConfigComponent.write(prefix + "topSalesNum", value);
例如,您用的是mongodb配置保存方式,您可以自我实现DynamicStorageStrategy接口。并提高装配优先级即可。
@Component
@Primary
public class MyDynamicStorageStrategy implements DynamicStorageStrategy {
.... impl
}