nacos支持配置文件热部署
1.原理
@RefreshScope注解实现的原理,是刷新bean
2.定义的变量,在代码中用变量来接,直接在代码块里面使用
示例 :
1.在配置文件定义一个share.config的属性,
share:
config: 测试配置2
2.代码中需要在本类上增加 @RefreshScope,@Value下的属性就会自动刷新
@RestController
@RequestMapping("/app")
@RefreshScope
public class AppController {
@Value("${share.config}")
private String shareConfig;
@GetMapping("/shareConfig")
public String shareConfig() {
return shareConfig;
}
}
3.工具类中的,定义的静态变量,调用静态方法(简单的)
原理:静态变量无法使用注解刷新,我们在调用静态方法时,重新获取变量最新的值,然后进行赋值
示例 :
1.在配置文件增加一个rabbitmq的属性
spring:
# rabbitmq 配置
rabbitmq:
username: user123
# 密码
password: 123456
2.在类上增加@RefreshScope 注解,用@Value 注入,在调用静态方法getMessageConnect()时,重新获取该bean,该类下的静态属性就会刷新
@Component
@RefreshScope
public class MessageUtil {
private static AuthorizeImpl AUTHORIZE;
private static String RABBITMQ_USERNAME;
private static String RABBITMQ_PASSWORD;
private static String MESSAGE_URL;
@Value("${spring.rabbitmq.username}")
public void setUsername(String username) {
MessageUtil.RABBITMQ_USERNAME = username;
}
@Value("${spring.rabbitmq.password}")
public void setPassword(String password) {
MessageUtil.RABBITMQ_PASSWORD = password;
}
@Value("${spring.message.url:null}")
public void setMessageUrl(String messageUrl) {
MessageUtil.MESSAGE_URL = messageUrl;
}
@Autowired
public void setAuthorizeImpl(AuthorizeImpl authorize) {
MessageUtil.AUTHORIZE = authorize;
}
public static MessageConnectVO getMessageConnect(String tokenId) {
MessageConnectVO messageConnectVO = new MessageConnectVO();
//这里重新获取一次Bean,取到最新的配置属性,因为静态方法里面不会自动刷新
BeanUtil.getInstanceByClassName(MessageUtil.class);
UserInfoDTO tokenInfo = AUTHORIZE.getUserInfoByTokenId(tokenId);
messageConnectVO.setUserId(tokenInfo.getUserId().toString());
messageConnectVO.setOrganizationId(tokenInfo.getOrganizationId().toString());
messageConnectVO.setPasscode(MessageUtil.RABBITMQ_PASSWORD);
messageConnectVO.setLogin(MessageUtil.RABBITMQ_USERNAME);
messageConnectVO.setUrl(MessageUtil.MESSAGE_URL);
return messageConnectVO;
}
}
4.框架通过配置文件读取之后,自动注入的属性相关配置,如数据源
示例:
1.这是配置文件里面的数据源:
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&useSSL=true&autoReconnect=true&failOverReadOnly=false
username: root
password: 123456
2.代码适配:需要再重新写一个数据源配置类,并在使用的类,和调用到数据源的bean上增加@RefreshScope注解
@Configuration
@MapperScan(basePackages = {"com.lzmispt.core.dao", "com.lzmispt.monitor.web.mapper"}, sqlSessionFactoryRef = "monitorSqlSessionFactory")
@RefreshScope
public class MonitorSourceConfig {
@Value("${spring.datasource.driver-class-name}")
private String driverClassName;
@Value("${spring.datasource.url}")
private String url;
@Value("${spring.datasource.username}")
private String username;
@Value("${spring.datasource.password}")
private String password;
@Bean("monitorDataSource")
@RefreshScope
public DataSource dataSource() {
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setDriverClassName(driverClassName);
druidDataSource.setUrl(url);
druidDataSource.setUsername(username);
druidDataSource.setPassword(password);
return druidDataSource;
}
@Bean("monitorTransactionManager")
@RefreshScope
public PlatformTransactionManager platformTransactionManager() {
return new DataSourceTransactionManager(dataSource());
}
@Bean("monitorSqlSessionFactory")
@RefreshScope
public SqlSessionFactory sqlSessionFactory() throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
DataSource dataSource = dataSource();
factoryBean.setDataSource(dataSource);
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
List<Resource> resources = new ArrayList<>();
getAdaptResources(resolver, resources, dataSource);
Resource[] resourceArr = new Resource[resources.size()];
factoryBean.setMapperLocations(resources.toArray(resourceArr));
return factoryBean.getObject();
}
private void getAdaptResources(ResourcePatternResolver resolver, List<Resource> resources, DataSource dataSource) throws Exception {
resources.addAll(Arrays.asList(resolver.getResources("classpath*:mapper/*.xml")));
}
}