读取nacos信息并动态监听nacos刷新数据

1、springboot、springcloud、springcloud alibaba 版本一定要对应上

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
	<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.2.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>

	
    <groupId>ms.platform</groupId>
    <artifactId>base-spring-cloud</artifactId>
    <packaging>pom</packaging>
    <version>3.0.0-alibaba</version>

    <dependencyManagement>
        <dependencies>
            <!--Spring Cloud Alibaba 的版本信息-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.2.3.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--Spring Cloud 的版本信息-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR8</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>


        </dependencies>
    </dependencyManagement>

</project>

2、完整版xml如下:
 

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <parent>
        <groupId>ms.platform</groupId>
        <artifactId>base-spring-cloud</artifactId>
        <version>3.0.0-alibaba</version>
    </parent>

	<modelVersion>4.0.0</modelVersion>
	<groupId>ms.platform</groupId>
    <artifactId>ms-dependency</artifactId>
    <version>3.0.1</version>
    <packaging>pom</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	<ms.ops.version>3.0.1</ms.ops.version>
	<ms.ops.old.version>1.5.9</ms.ops.old.version>
        <ms.common.version>1.4.1</ms.common.version>
	<mybatis-plus-boot-starter>2.2.0</mybatis-plus-boot-starter>
        <mybatisplus.version>2.2.0</mybatisplus.version>
    </properties>

    

    <dependencyManagement>
        <dependencies>
			<!-- 配置中心 -->
			<dependency>
				<groupId>ms.platform</groupId>
				<artifactId>ops-config</artifactId>
				<version>${ms.ops.version}</version>
			</dependency>
            <dependency>
                <groupId>ms.platform</groupId>
                <artifactId>ops-rpc-client</artifactId>
                <version>${ms.ops.version}</version>
            </dependency>
            <dependency>
                <groupId>ms.platform</groupId>
                <artifactId>ops-ice</artifactId>
                <version>${ms.ops.old.version}</version>
            </dependency>
            <dependency>
                <groupId>ms.platform</groupId>
                <artifactId>base-framework</artifactId>
                <version>${ms.ops.old.version}</version>
            </dependency>
            <dependency>
                <groupId>ms.platform</groupId>
                <artifactId>ops-mq-mix</artifactId>
                <version>${ms.ops.version}</version>
            </dependency>
            <dependency>
                <groupId>ms.platform</groupId>
                <artifactId>ops-mq</artifactId>
                <version>${ms.ops.version}</version>
            </dependency>
            <dependency>
                <groupId>ms.platform</groupId>
                <artifactId>ops-mq-consumer</artifactId>
                <version>${ms.ops.version}</version>
            </dependency>
            <dependency>
                <groupId>ms.platform</groupId>
                <artifactId>ops-mq-producer</artifactId>
                <version>${ms.ops.version}</version>
            </dependency>
            <dependency>
                <groupId>ms.platform</groupId>
                <artifactId>ops-oss</artifactId>
                <version>${ms.ops.version}</version>
            </dependency>
            <dependency>
                <groupId>ms.platform</groupId>
                <artifactId>ops-zipkin</artifactId>
                <version>${ms.ops.old.version}</version>
            </dependency>
            <dependency>
                <groupId>ms.platform</groupId>
                <artifactId>ops-utils</artifactId>
                <version>${ms.ops.version}</version>
            </dependency>
            <!-- 调用会员域接口 -->
            <dependency>
                <groupId>ms.platform</groupId>
                <artifactId>ops-user</artifactId>
                <version>${ms.ops.version}</version>
            </dependency>
            <dependency>
                <groupId>io.jsonwebtoken</groupId>
                <artifactId>jjwt</artifactId>
                <version>0.9.0</version>
            </dependency>

            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>${mybatis-plus-boot-starter}</version>
            </dependency>
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus</artifactId>
                <version>${mybatisplus.version}</version>
            </dependency>

            <!-- mybatis分页插件 -->
            <dependency>
			   <groupId>com.github.pagehelper</groupId>
			   <artifactId>pagehelper-spring-boot-starter</artifactId>
			   <version>1.2.3</version>
			</dependency>

        </dependencies>
    </dependencyManagement>

    <dependencies>
        <!-- 引入spring boot mybatis 依赖包
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
        </dependency> -->

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>
        <!-- JSR 验证框架 -->
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
        </dependency>

        <!-- @Inject -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
        </dependency>

        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-core-asl</artifactId>
        </dependency>
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-mapper-asl</artifactId>
        </dependency>

        <dependency>
            <groupId>ms.common</groupId>
            <artifactId>common-bo</artifactId>
            <version>${ms.common.version}</version>
        </dependency>
        <dependency>
            <groupId>ms.common</groupId>
            <artifactId>common-utils</artifactId>
            <version>${ms.common.version}</version>
        </dependency>
        <dependency>
            <groupId>ms.common</groupId>
            <artifactId>common-spring-context</artifactId>
            <version>${ms.common.version}</version>
        </dependency>

        <dependency>
            <groupId>ms.platform</groupId>
            <artifactId>ops-cloud</artifactId>
            <version>${ms.ops.version}</version>
        </dependency>

        <!-- redis -->
        <dependency>
            <groupId>ms.platform</groupId>
            <artifactId>ops-cache-redis</artifactId>
            <version>${ms.ops.version}</version>
        </dependency>
        

        <!-- 需要调用链监控引入
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-sleuth</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zipkin</artifactId>
        </dependency>  -->

        <!-- swagger 文档 -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
        </dependency>
		
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- test -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
		
		<dependency>
            <groupId>commons-beanutils</groupId>
			<artifactId>commons-beanutils</artifactId>
			<version>1.9.3</version>
        </dependency>
		
		<dependency>
            <groupId>org.mockito</groupId>
			<artifactId>mockito-junit-jupiter</artifactId>
			<version>4.8.1</version>
        </dependency>
		
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-validator</artifactId>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-validator-cdi</artifactId>
		</dependency>
		<dependency>
			<groupId>javax.validation</groupId>
			<artifactId>validation-api</artifactId>
		</dependency>
		
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.11.1</version>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-annotations</artifactId>
			<version>2.11.1</version>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-core</artifactId>
			<version>2.11.1</version>
		</dependency>


    </dependencies>

</project>

3、引入nacos依赖

<dependency>
            <groupId>com.alibaba.nacos</groupId>
            <artifactId>nacos-client</artifactId>
        </dependency>

4、自定义类:NacosPlatformPropertyConfigListener 

package com.ms.platform.configcenter.listener;

import java.io.IOException;
import java.io.StringReader;
import java.util.Properties;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.event.ApplicationStartingEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import com.ms.common.bo.prop.PlatformProp;
import com.ms.platform.configcenter.ServerConfigUtil;

/**
 * 
 * @ClassName: NacosPlatformPropertyConfigListener
 * @Description: 获取nacos的监听类,springboot启动时调用
 * @author dingjy
 * @date 2023年9月25日 下午2:22:36
 */
@Component
public class NacosPlatformPropertyConfigListener implements ApplicationListener<ApplicationStartingEvent>, Ordered {

	private Logger logger = LoggerFactory.getLogger(NacosPlatformPropertyConfigListener.class);

	private static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 4, 1, TimeUnit.SECONDS,
			new LinkedBlockingDeque<>(100), new ThreadPoolExecutor.CallerRunsPolicy());

	private static String DEFAULT_CONFIG_PREFIX = "bootstrap";
	private static String DEFAULT_CONFIG_CONNECTION_SYMBOL = "-";
	private static String DEFAULT_SUFFIX_CONNECTION_SYMBOL = ".";
	private static String DEFAULT_CONFIG_SUFFIX = "properties";

	public NacosPlatformPropertyConfigListener() {
		super();
	}

	@Override
	public void onApplicationEvent(ApplicationStartingEvent event) {
		if (event instanceof ApplicationStartingEvent) {// 项目启动时读取nacos配置信息
			onApplicationStartEvent((ApplicationStartingEvent) event);
		}
	}

	private void onApplicationStartEvent(ApplicationStartingEvent event) {
		// 防止二次加载
		String serverAddr = PlatformProp.getProperty("spring.cloud.nacos.discovery.server-addr", "").trim();
		if (StringUtils.isNoneBlank(serverAddr)) {
			return;
		}
		// 读取启动环境(dev/pre/prd)的配置文件
		String configName = null;
		String env = null;
		try {
			//获取公共配置
			configName = StringUtils.join(DEFAULT_CONFIG_PREFIX, DEFAULT_SUFFIX_CONNECTION_SYMBOL,
					DEFAULT_CONFIG_SUFFIX);
			PlatformProp.init(configName);
			//获取不同环境的配置
			if (event.getArgs() == null || event.getArgs().length == 0) {
				env = PlatformProp.getProperty("spring.profiles.active");
			} else {//读取启动参数
				ServerConfigUtil.readConfigArgs(event.getArgs());
				env = PlatformProp.getProperty("--spring.profiles.active");
			}
			if (StringUtils.isBlank(env)) {
				logger.error("++++++++++请选择启动环境++++++++++");
				throw new RuntimeException("请选择启动环境");
			}
			configName = StringUtils.join(DEFAULT_CONFIG_PREFIX, DEFAULT_CONFIG_CONNECTION_SYMBOL, env,
					DEFAULT_SUFFIX_CONNECTION_SYMBOL, DEFAULT_CONFIG_SUFFIX);
			// 读取文件配置
			PlatformProp.init(configName);
		} catch (IOException e) {
			logger.error("++++++++++读取" + env + "环境的配置文件错误++++++++++");
			throw new RuntimeException("读取" + env + "环境的配置文件错误");
		}

		try {
			serverAddr = PlatformProp.getProperty("spring.cloud.nacos.discovery.server-addr", "").trim();
			String applicationName = PlatformProp.getProperty("spring.application.name", "").trim();
			String nameSpace = PlatformProp.getProperty("spring.cloud.nacos.discovery.namespace", "").trim();
			String group = PlatformProp.getProperty("spring.cloud.nacos.discovery.group", "DEFAULT_GROUP").trim();
			String userName = PlatformProp.getProperty("spring.cloud.nacos.discovery.username", "").trim();
			String pwd = PlatformProp.getProperty("spring.cloud.nacos.discovery.password", "").trim();
			if (StringUtils.isBlank(serverAddr)) {
				throw new RuntimeException("请设置nacos配置中心地址");
			}
			if (StringUtils.isBlank(applicationName)) {
				throw new RuntimeException("请设置项目名称");
			}
			if (StringUtils.isBlank(nameSpace)) {
				throw new RuntimeException("请设置nacos配置中心namaspace");
			}
			if (StringUtils.isBlank(userName)) {
				throw new RuntimeException("请设置nacos配置中username");
			}
			if (StringUtils.isBlank(pwd)) {
				throw new RuntimeException("请设置nacos配置中心password");
			}
			String dataId = StringUtils.join(applicationName, DEFAULT_CONFIG_CONNECTION_SYMBOL, env,
					DEFAULT_SUFFIX_CONNECTION_SYMBOL, DEFAULT_CONFIG_SUFFIX);
			Properties properties = new Properties();
			properties.put(PropertyKeyConst.SERVER_ADDR, serverAddr);
			properties.put(PropertyKeyConst.NAMESPACE, nameSpace);
			properties.put(PropertyKeyConst.USERNAME, userName);
			properties.put(PropertyKeyConst.PASSWORD, pwd);
			ConfigService configService = NacosFactory.createConfigService(properties);
			String content = configService.getConfig(dataId, group, 5000);
			if (StringUtils.isBlank(content)) {
				throw new RuntimeException("请设置nacos配置中心配置信息");
			}
			try {
				PlatformProp.getEnv().load(new StringReader(content));
			} catch (Exception e) {
				throw new RuntimeException("nacos配置中心信息解析异常", e);
			}
			configService.addListener(dataId, group, new Listener() { // 添加监听
				@Override
				public void receiveConfigInfo(String configInfo) {
					try {
						logger.info("..........nacos配置信息同步success..........");
						PlatformProp.getEnv().load(new StringReader(configInfo));
					} catch (Exception e) {
						throw new RuntimeException("nacos配置中心新增信息解析异常", e);
					}
				}

				@Override
				public Executor getExecutor() {
					return threadPoolExecutor;
				}
			});
		} catch (NacosException e) {
			// 读取配置超时或网络异常,抛出 NacosException 异常。
			e.printStackTrace();
		}

	}

	@Override
	public int getOrder() {
		return HIGHEST_PRECEDENCE;
	}
}

5、PlatformProp类如下:

package com.ms.common.bo.prop;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Created by Joey on 2017/3/21 0021.
 * <p>
 * 配置读取
 */
public class PlatformProp implements Serializable {

    private static final long serialVersionUID = 2313107748344879601L;
    private static Logger logger = LoggerFactory.getLogger(PlatformProp.class);

    private PlatformProp() {
    }

    private static Properties env = new Properties();
    private static Set<String> fileHistorySet = new HashSet<>();

    public static void init(String... filePaths) throws IOException {

        logger.info("----------init config");
        for (String filePath : filePaths) {
            if (null == filePath) {
                continue;
            }
            if(fileHistorySet.contains(filePath)){
                return;
            }
            fileHistorySet.add(filePath);

            InputStream in = null;
            try {
                File file = new File(filePath);
                if(file.exists()){
                    in = new FileInputStream(filePath);
                }else {
                    in = PlatformProp.class.getClassLoader().getResourceAsStream(filePath);
                    if (null == in) {
                        in = PlatformProp.class.getResourceAsStream(filePath);
                    }
                }
                if(null!=in){
                    env.load(new InputStreamReader(in, "utf-8"));
                }else{
                    logger.error("-------file not found");
                }
            } catch (IOException e) {
                throw e;
            } finally {
                if (null != in) {
                    in.close();
                }
            }
        }
    }

    public static void initClassPath(String... classFilePaths) throws IOException {
        init(classFilePaths);
    }
    
    public static Properties getEnv() {
		return env;
	}

	public static Set<Object> keySet() {
        return env.keySet();
    }
    
    public static Set<Entry<Object, Object>> entrySet(){
    	return env.entrySet();
    }

    public static String getProperty(String propName, String defaultValue) {
        return env.getProperty(propName, defaultValue);
    }

    public static String getProperty(String propName) {
        return env.getProperty(propName);
    }

    public static void setProperty(String propName, String value) {
        env.setProperty(propName, value);
    }

}

6、ServerConfigUtil类如下:

package com.ms.platform.configcenter;

import com.ms.common.bo.prop.PlatformProp;

public class ServerConfigUtil {

    /**
     * 读取配置中心启动配置
     * @param args
     */
    public static void readConfigArgs(String[] args){
        if(null!=args && args.length>0){
            for (int i = 0; i < args.length; i++) {
                String configArg = args[i];
                if(null==configArg){
                    continue;
                }
                String[] configArgs = configArg.split("=");
                if(configArgs.length<2){
                    continue;
                }
                PlatformProp.setProperty(configArgs[0],configArgs[1]);
            }
        }
    }

}

7、在resource下创建目录:META-INF/spring.factories


# Application Listeners
org.springframework.context.ApplicationListener=\
com.ms.platform.configcenter.listener.NacosPlatformPropertyConfigListener

----------------------引入nacos配置中心实现步骤-------------------------------

1、在每个能启动的项目中(xxx.xxx.weizhi、xxx.xxx.api)的pom文件中添加依赖:

<!-- 添加nacos配置 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        
    
 2、在每个能启动的项目中(xxx.xxx.weizhi、xxx.xxx.api)的resources目录下添加不同环境的配置文件:

名称分别为:bootstrap.properties(引导文件)、bootstrap-dev.properties(开发环境)、bootstrap-pre.properties(预生产环境)bootstrap-prod.properties(生产环境)

bootstrap.properties:

#指定默认启动环境
spring.profiles.active=dev
#项目名称
spring.application.name=ms.roster.weizhi
#去除相同的bean定义
spring.main.allow-bean-definition-overriding=true 

bootstrap-dev.properties:

#注册中心地址•
spring.cloud.nacos.discovery.server-addr=192.168.2.155:8848
#注册中心账户•
spring.cloud.nacos.discovery.username=nacos
#注册中心密码
spring.cloud.nacos.discovery.password=nacos
#注册中心命名空间
spring.cloud.nacos.discovery.namespace=ms-dev 
#注册中心分组••
spring.cloud.nacos.discovery.group=DEFAULT_GROUP
​
#配置中心地址
spring.cloud.nacos.config.server-addr=192.168.2.155:8848
#配置中心账户•
spring.cloud.nacos.config.username=nacos
#配置中心密码
spring.cloud.nacos.config.password=nacos
#配置中心命名空间
spring.cloud.nacos.config.namespace=ms-dev
#配置中心文件后缀
spring.cloud.nacos.config.file-extension=properties
#配置中心分组••
spring.cloud.nacos.config.group=DEFAULT_GROUP

bootstrap-pre.properties、bootstrap-prod.properties依葫芦画瓢即可

3、创建不同环境的命名空间:

其中,命名空间ID是需要填写在bootstrap-${profiles}.properties文件当中:

4、将项目原先所在的配置信息从pre/prd环境下载下来,copy到nacos对应的命名空间下,名称为: ${spring.application.name}--${spring.profiles.active}.${file-extension}

5、IDE启动可以不加任何入参,直接debug/run即可,默认是dev环境的配置,也可以自定义启动环境,如下图所示:

6、服务器启动方式如下:

java -Xms256m -Xmx512m -jar xxx.xxx.xxx.jar --spring.profiles.active=${profiles}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值