java springboot本地调试动态修改nacos配置信息

一、需求

我本地项目想直接连接测试环境nacos,由于nacos中的配置信息我不能修改,否则测试环境会出问题。但是我还想改配置怎么办呢?

可以在本地springboot项目启动拿到nacos配置时修改。

二、举个例子

例如:测试环境nacos中配置的server.tomcat.basedir配置(tomcat临时目录),在我本地无法创建相应的文件夹,导致无法启动项目,所以我就只能修改server.tomcat.basedir的值(还不能修改nacos云配置)。

无法创建对应目录,如图:

 项目启动报错,如图:

 

三、解决办法

第一种方法,借助idea的断点调试功能进行修改

1、我们找到NacosPropertySourceBuilder类的loadNacosData方法,把断点打到如图位置

 2、使用Evaluate执行dataMap.put()方法把值重新覆盖就可以了。

 以上操作,只适合临时启动用,每次启动都要修改一下,很麻烦。可以使用第二种方法。

第二种方法,使用代码修改

1、先自定义一个类实现SpringApplicationRunListener接口。

SpringApplicationRunListener是springboot的生命周期,不懂可以参考:springboot扩展点_现实、太残忍的博客-CSDN博客_springboot扩展点


@Slf4j
public class LocalHostSpringApplicationRunListener implements SpringApplicationRunListener {

    /**
     * 必须添加参数为SpringApplication application和String[] args构造方法,否则启动报错
     * @param application
     * @param args
     */
    public LocalHostSpringApplicationRunListener(SpringApplication application, String[] args) {
    }

    @Override
    public void starting() {
    }

    @Override
    public void environmentPrepared(ConfigurableEnvironment environment) {
    }

    /**
     * 环境上下文准备完成时
     * @param context the application context
     */
    @Override
    public void contextPrepared(ConfigurableApplicationContext context) {
        //判断上下文环境是ServletWebServer环境
        if(context instanceof AnnotationConfigServletWebServerApplicationContext){
            //从上下文环境中获取总配置信息
            MutablePropertySources mutablePropertySources = context.getEnvironment().getPropertySources();
            //获取nacos配置信息
            CompositePropertySource bootstrapPropertiesCompositePropertySource = (CompositePropertySource)mutablePropertySources.get("bootstrapProperties");
            //获取nacos配置信息中的配置信息(包装了好几层)
            for (PropertySource compositePropertySource : bootstrapPropertiesCompositePropertySource.getPropertySources()) {
                for (PropertySource nacosPropertySource : ((CompositePropertySource) compositePropertySource).getPropertySources()) {
                    //最终拿到对应的配置文件信息
                    NacosPropertySource nacosPropertySourceTarget = (NacosPropertySource) nacosPropertySource;
                    //找到你要修改的文件名称(dataId)
                    if("sys-test.properties".equals(nacosPropertySourceTarget.getDataId())){
                        //修改值
                        Map<String, Object> source = nacosPropertySourceTarget.getSource();
                        source.put("server.tomcat.basedir","/tmp");
                        log.info("已修改server.tomcat.basedir为/tmp");
                    }
                };
            };
        }
    }

    @Override
    public void contextLoaded(ConfigurableApplicationContext context) {
    }

    @Override
    public void started(ConfigurableApplicationContext context) {

    }

    @Override
    public void running(ConfigurableApplicationContext context) {

    }

    @Override
    public void failed(ConfigurableApplicationContext context, Throwable exception) {

    }
}

2、在resources文件夹下的META-INF文件夹创建一个spring.factories文件

解释:Spring factories是 Spring Boot 一种解耦的扩展机制,仿照了 Java 中 SPI 的扩展机制,可以实现自动加载可扫描包之外的 Bean。

 

 3、完毕

方法二具体原理:

1、通过断点可以得知,nacos获取配置阶段发生在springboot生命周期的“上下文准备阶段”。
所以是spingboot的prepareContext方法,具体发生在执行applyInitializers方法中。

其中包括一个PropertySourceBootstrapConfiguration类是springcloud的用于远程配置处理的类。

从代码中我们可以看到listeners.contextPrepared(context);,所以我们正好可以利用springboot生命周期的“上下文准备阶段”进行nacos配置的修改。

2、进行SpringApplicationRunListener的springboot生命周期接口实现

ConfigurableApplicationContext是应用的上下文信息,里面包含Environment环境信息。

Environment环境信息里面包含PropertySources配置信息。

因为配置信息有多个(本地配置,nacos配置等),所以我们要找到nacos的配置信息,一层一层获取到map然后修改

Spring Boot 2.x中整合Nacos配置服务,可以通过Nacos提供的Spring Cloud Config支持类来实现配置获取和刷新。 首先,在pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> ``` 然后,在application.properties(或application.yml)文件中配置Nacos的服务器地址、命名空间、应用名、配置信息等: ```properties spring.cloud.nacos.config.server-addr=127.0.0.1:8848 spring.cloud.nacos.config.namespace=xxx spring.cloud.nacos.config.group=xxx spring.cloud.nacos.config.prefix=xxx spring.cloud.nacos.config.file-extension=properties ``` 其中,server-addr是Nacos服务器的地址,namespace是命名空间,group是配置分组,prefix是配置前缀,file-extension是配置文件的扩展名。 然后,可以通过@Value注解来获取配置信息: ```java @Value("${xxx}") private String xxx; ``` 如果需要动态刷新配置,可以添加@RefreshScope注解,并在配置类中添加@NacosConfigListener注解监听配置变化: ```java @Configuration @RefreshScope public class Config { @Value("${xxx}") private String xxx; @NacosConfigListener(dataId = "xxx", groupId = "xxx", timeout = 5000) public void onMessage(String config) { // 重新加载配置 xxx = config; } } ``` 其中,dataId是配置信息的ID,groupId是配置分组的ID,timeout是超时时间。 这样,当Nacos配置信息发生变化时,就会触发onMessage方法重新加载配置信息
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值