有关Springboot引入Apollo配置中心后启动时读取本地配置文件的问题

今天在做一个Appllo动态加解密的功能,需要修改Apollo-client的源码。

目前源码修改是正常的,在项目启动时也能调用到Apollo的DefaultConfig的函数,就是在初始化解密的时候有点,小问题:

访问不到本地的配置文件,显示‘null’

上源码及相关代码:

/**
 * @author Jason Song(song_s@ctrip.com)
 */
@Component
public class DefaultConfig extends AbstractConfig implements RepositoryChangeListener {
  private static final Logger logger = LoggerFactory.getLogger(DefaultConfig.class);
  private final String m_namespace;
  private final Properties m_resourceProperties;
  private final AtomicReference<Properties> m_configProperties;
  private final ConfigRepository m_configRepository;
  private final RateLimiter m_warnLogRateLimiter;

  private volatile ConfigSourceType m_sourceType = ConfigSourceType.NONE;

  @Value("${jasypt.encryptor.password}")
  private String DECRYPT_KEY;

最下面的是AES解密用的Key

这是配置更新和初始化会用到的函数,是我更改后的

private void updateConfig(Properties newConfigProperties, ConfigSourceType sourceType) {
	  Set<Object> keys = newConfigProperties.keySet();
	    for (Object k : keys) {
	        String key = k.toString();
	        String value = newConfigProperties.getProperty(key);
	        // 加密Value
	        if (value.startsWith("ENC(") && value.endsWith(")")) {
	            logger.info("加密Value {}", value);
	            // 解密然后重新赋值
	            try {
	                //String decryptValue = AesEncryptUtils.aesDecrypt(value.substring(3, value.length()-1), DECRYPT_KEY);
	                String decryptValue = AESUtil.decrypt(value.substring(3, value.length()-1), DECRYPT_KEY);
	                newConfigProperties.setProperty(key, decryptValue);
	            } catch (Exception e) {
	                logger.error("加密配置解密失败", e);
	            }
	        }
	    }
	    m_configProperties.set(newConfigProperties);
	    m_sourceType = sourceType;
  }

DECRYPT_KEY 读取是空(null)
image

启动类的ComponentScan已配置
image

配置文件

server.port=XXX
app.id=XXX
apollo.meta=http://XXX
apollo.bootstrap.enabled=true
apollo.bootstrap.namespaces=application
jasypt.encryptor.password=somepwd

目前还在排查中,
猜想是Apollo的配置中心文件覆盖了本地的配配置文件,因为在console中Apollo的配置加载是最先的,然后namespace与本地文件的相同,所以导致了覆盖(猜)
又或者简单一点的,是我@Value的用法有问题。

还请有经验的老哥指点一二

%E5%9B%BE%E7%89%87
:joy:

哈哈,等我回去了把解决办法带上

1 个赞

本贴最后找出来的问题:

因为Apollo的配置读取是在程序启动最前,所以导致了springboot的配置类没有装载

目前用了一个比较简单的解决办法:

在springboot启动类的Main函数中使用java原生的文件流读取application.properties的配置

springboot启动类:

    private static String PWD;
	
	
	public static String getPWD() {
		return PWD;
	}

	public static void setPWD(String pWD) {
		PWD = pWD;
	}

	public static void main(String[] args) throws IOException {
        //读取文件
		File file = ResourceUtils.getFile("classpath:application.properties");
		InputStream inputStream = new FileInputStream(file);
		byte[] bytes = new byte[0];
		bytes = new byte[inputStream.available()];
		inputStream.read(bytes);
		String str = new String(bytes);
        //读取AES加密秘钥
		ApolloEncryptionTestApplication.setPWD(str.substring(str.indexOf("jasypt.encryptor.password=")+"jasypt.encryptor.password=".length()));
		SpringApplication.run(ApolloEncryptionTestApplication.class, args);
	}
1 个赞

你好,我也遇到这种情况,请问有什么更好的方法读取配置

试试用bootstrap.yml或者bootstrap.properties?
在application.yml同级路径下创建该文件添加配置
我最近学了SpringCloud才发现这个命名的配置文件会优于application.yml加载
不过还没有实测过,你可以尝试一下!