springboot高级特性之修改配置文件

应用场景:

想动态调整Spirngboot的yml配置文件内容。比如数据库链接信息,或者说mq链接信息、监听队列的调整。

本人这里以rabbitmq消息队列为例,@RabbitListener(queues = "xxx") 监听者的这个队列名,每次在修改消息队列名称时都要手动调整yml然后重启项目,为了解决这个问题看了两天的源码才知道可以这样调整。

1、将mq的所有信息都保存在数据库里,项目初始化的时候从数据库读取。在Springboot中,需要通过ApplicationListener 接口来获取配置信息,onApplicationEvent这个方法执行的时候所有信息都是空的,所以需要在此方法里进行数据库连接。

import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import org.springframework.boot.origin.OriginTrackedValue;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertySource;

import javax.annotation.PostConstruct;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Map;
import java.util.Properties;

@Configuration
public class RabbitMqConfig  implements ApplicationListener<ApplicationEnvironmentPreparedEvent> {

    @Autowired
    private SqlSessionTemplate sqlSessionTemplate;
    private String host;
    private String port;
    private String username;
    private String password;

    @PostConstruct
    public void init() {
        SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory().openSession();
        YumingMapper mapper = sqlSession.getMapper(YumingMapper.class);
        Map<String, String> config = mapper.queryRabbitMqConfigInfo();
        host = config.get("host");
        port = config.get("port");
        username = config.get("username");
        password = config.get("password");
	}


	@Bean
    public ConnectionFactory connectionFactory() {
    	// 重置yml 里的配置文件
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
        connectionFactory.setHost(host);
        connectionFactory.setPort(Integer.parseInt(port));
        connectionFactory.setUsername(username);
        connectionFactory.setPassword(password);
        return connectionFactory;
    }


	@Override
	public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {

		Connection conn = null;
		Statement st = null;
		ResultSet rs = null;
		// 获取spring Environment
		MutablePropertySources propertySources = event.getEnvironment().getPropertySources();
		// 配置放在了application-pro或者是application-dev 中 赋值复制需要在其中赋值
		for (PropertySource<?> propertySource : propertySources) {
			boolean applicationConfig = propertySource.getName().contains("application");
			if (!applicationConfig) {
				continue;
			}
			// 获取上文的application集合中获取数据库连接
			Map<String, OriginTrackedValue> dataBaseSource =
					(Map<String, OriginTrackedValue>)propertySource.getSource();
//			String driverClass = String.valueOf(dataBaseSource.get("spring.datasource.driver-class-name").getValue());
			String url = String.valueOf(dataBaseSource.get("spring.datasource.url").getValue());
			String user = String.valueOf(dataBaseSource.get("spring.datasource.username").getValue());
			String password = String.valueOf(dataBaseSource.get("spring.datasource.password").getValue());
			// 因为在spring初始化之前 所有不能使用注解 所以需要jdbc直接连接数据库 首先建立驱动
			try {
				Class.forName("com.mysql.cj.jdbc.Driver");
				conn = DriverManager.getConnection(url, user, password);
				// 1、获取连接对象
				// 2、创建statement类对象,用来执行SQL语句!!
				st = conn.createStatement();
				// 3、创建sql查询语句
				String sql = "select * from jl_config";
				// 4、执行sql语句并且换回一个查询的结果集
				rs = st.executeQuery(sql);
				while (rs.next()) {
					// 获取数据库中的数据
					String jlappid = rs.getString("jlappid");
					int jlstore_id = rs.getInt("jlstore_id");

					String goodsQueneName = "goods_list_" + jlappid;
					String orderQueneName = "xxxie_store_gongban" + jlstore_id;
					String orderRoutingKey = "order_" + jlstore_id;

					ConfigurableEnvironment environment = event.getEnvironment();
					Properties props = new Properties();
					props.put("mq.goods.queneName", goodsQueneName);
					props.put("mq.order.queneName", orderQueneName);
					props.put("mq.order.routingKey", orderRoutingKey);
					environment.getPropertySources().addFirst(new PropertiesPropertySource("decrypted_properties", props));
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

	}
}

2、新建resources/META_INF/下新建spring.factories文件,输入以下内容.就是类路径。

org.springframework.context.ApplicationListener = xxxx.RabbitMqConfig

3、重启项目就能达到通过数据获取覆盖Springbootymp配置文件的覆盖操作。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Spring Boot提供了很多高级特性,其中一些重要的特性包括: 1. 自动配置(Auto-Configuration):Spring Boot通过自动配置机制,根据类路径上的依赖和用户的自定义配置,自动为应用程序配置各种功能和服务。这大大简化了应用程序的配置过程。 2. 起步依赖(Starter Dependencies):Spring Boot提供了一系列起步依赖,可以快速引入常用的功能模块和库。通过引入适当的起步依赖,可以简化应用程序的构建和部署过程。 3. Actuator:Spring Boot Actuator提供了一组管理和监控应用程序的端点(Endpoints),可以通过HTTP或JMX来访问这些端点。它可以帮助开发人员监控应用程序的运行状态、健康状况和性能指标等。 4. 外部化配置(Externalized Configuration):Spring Boot支持将应用程序的配置信息外部化,可以使用不同的配置文件(如application.propertiesapplication.yml)来配置应用程序的各种属性和参数。 5. Spring Boot Test:Spring Boot提供了一套方便的测试框架,可以帮助开发人员编写单元测试、集成测试和端到端测试。通过使用@SpringBootTest注解和其他相关注解,可以轻松地进行各种类型的测试。 6. Spring Boot DevTools:Spring Boot DevTools是一个开发工具,它提供了很多实用的功能,如自动应用程序重启、自动刷新页面和CSS/JS的热部署等。它可以大大提高开发人员的开发效率。 这些高级特性使得开发人员能够更加便捷地构建、测试和部署Spring Boot应用程序,并且提供了更好的性能和可靠性。<span class="em">1</span><span class="em">2</span><span class="em">3</span>

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小tu豆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值