当前位置: 首页 > news >正文

网站设置了权限承德信息网58

网站设置了权限,承德信息网58,推广自身网站,dede网站地图怎么做项目启动怎么读取的配置信息 自动装配 SpringBoot 自动装配机制 加载 WEB/INF spring.factories 会将如下几个Bean加载到ioc 容器中 BeanConditionalOnMissingBeanpublic NacosConfigProperties nacosConfigProperties() {return new NacosConfigProperties();}BeanCondition…项目启动怎么读取的配置信息 自动装配 SpringBoot 自动装配机制 加载 WEB/INF spring.factories 会将如下几个Bean加载到ioc 容器中 BeanConditionalOnMissingBeanpublic NacosConfigProperties nacosConfigProperties() {return new NacosConfigProperties();}BeanConditionalOnMissingBeanpublic NacosConfigManager nacosConfigManager(NacosConfigProperties nacosConfigProperties) {return new NacosConfigManager(nacosConfigProperties);}Beanpublic NacosPropertySourceLocator nacosPropertySourceLocator(NacosConfigManager nacosConfigManager) {return new NacosPropertySourceLocator(nacosConfigManager);}/*** Compatible with bootstrap way to start.* param beans configurationPropertiesBeans* return configurationPropertiesRebinder*/BeanConditionalOnMissingBean(search SearchStrategy.CURRENT)ConditionalOnNonDefaultBehaviorpublic ConfigurationPropertiesRebinder smartConfigurationPropertiesRebinder(ConfigurationPropertiesBeans beans) {// If using default behavior, not use SmartConfigurationPropertiesRebinder.// Minimize te possibility of making mistakes.return new SmartConfigurationPropertiesRebinder(beans);}在SpringBoot启动的时候会将触发 PropertySourceLocator的locate方法去读取配置 而NacosPropertySourceLocator实现了PropertySourceLocator接口所以会触发NacosPropertySourceLocator的locate方法 Overridepublic PropertySource? locate(Environment env) {//设置 Environment(上下文环境)nacosConfigProperties.setEnvironment(env);//获取远程调用服务 ConfigServiceConfigService configService nacosConfigManager.getConfigService();if (null configService) {log.warn(no instance of config service found, cant load config from nacos);return null;}//超时时间 3000long timeout nacosConfigProperties.getTimeout();nacosPropertySourceBuilder new NacosPropertySourceBuilder(configService,timeout);String name nacosConfigProperties.getName();//应用名String dataIdPrefix nacosConfigProperties.getPrefix();if (StringUtils.isEmpty(dataIdPrefix)) {dataIdPrefix name;}if (StringUtils.isEmpty(dataIdPrefix)) {dataIdPrefix env.getProperty(spring.application.name);}CompositePropertySource composite new CompositePropertySource(NACOS_PROPERTY_SOURCE_NAME);//共享配置 shared-configsloadSharedConfiguration(composite);//扩展配置 extension-configsloadExtConfiguration(composite);//本地配置 dataIdloadApplicationConfiguration(composite, dataIdPrefix, nacosConfigProperties, env);return composite;}共享配置加载 private void loadSharedConfiguration(CompositePropertySource compositePropertySource) {ListNacosConfigProperties.Config sharedConfigs nacosConfigProperties.getSharedConfigs();//如果配置了共享配置 if (!CollectionUtils.isEmpty(sharedConfigs)) {//检查共享配置checkConfiguration(sharedConfigs, shared-configs);//加载配置信息loadNacosConfiguration(compositePropertySource, sharedConfigs);}}扩展配置加载 private void loadExtConfiguration(CompositePropertySource compositePropertySource) {ListNacosConfigProperties.Config extConfigs nacosConfigProperties.getExtensionConfigs();//如果配置了扩展配置 if (!CollectionUtils.isEmpty(extConfigs)) {//扩展配置检查checkConfiguration(extConfigs, extension-configs);//加载配置信息loadNacosConfiguration(compositePropertySource, extConfigs);}}private void loadNacosConfiguration(final CompositePropertySource composite,ListNacosConfigProperties.Config configs) {//遍历配置信息 for (NacosConfigProperties.Config config : configs) {//获取配置内容的数据格式 比如yaml 之类的String fileExtension config.getFileExtension();//如果是空if (StringUtils.isEmpty(fileExtension)) {//从DataId里面获取fileExtension NacosDataParserHandler.getInstance().getFileExtension(config.getDataId());}//加载配置信息loadNacosDataIfPresent(composite, config.getDataId(), config.getGroup(),fileExtension, config.isRefresh());}}本地配置加载 private void loadApplicationConfiguration(CompositePropertySource compositePropertySource, String dataIdPrefix,NacosConfigProperties properties, Environment environment) {//文件扩展名 .ymal/properties spring.cloud.nacos.config.file-extensionString fileExtension properties.getFileExtension();//GroupString nacosGroup properties.getGroup();// load directly once by default//加载 配置文件名的文件loadNacosDataIfPresent(compositePropertySource, dataIdPrefix, nacosGroup,fileExtension, true);// load with suffix, which have a higher priority than the default//加载 配置文件名.yml/Property的文件loadNacosDataIfPresent(compositePropertySource,dataIdPrefix DOT fileExtension, nacosGroup, fileExtension, true);// Loaded with profile, which have a higher priority than the suffix//根据 .dev/.prd 进行逐项加载for (String profile : environment.getActiveProfiles()) {String dataId dataIdPrefix SEP1 profile DOT fileExtension;loadNacosDataIfPresent(compositePropertySource, dataId, nacosGroup,fileExtension, true);}}加载配置信息 private void loadNacosDataIfPresent(final CompositePropertySource composite,final String dataId, final String group, String fileExtension,boolean isRefreshable) {if (null dataId || dataId.trim().length() 1) {return;}if (null group || group.trim().length() 1) {return;}//获取属性源 NacosPropertySource propertySource this.loadNacosPropertySource(dataId, group,fileExtension, isRefreshable);this.addFirstPropertySource(composite, propertySource, false);}private NacosPropertySource loadNacosPropertySource(final String dataId,final String group, String fileExtension, boolean isRefreshable) {//是否配置了刷新 每次判断会触发一次回调if (NacosContextRefresher.getRefreshCount() ! 0) {//不支持动态刷新 从本地缓存拿if (!isRefreshable) {return NacosPropertySourceRepository.getNacosPropertySource(dataId,group);}}//远程拿数据return nacosPropertySourceBuilder.build(dataId, group, fileExtension,isRefreshable);}本地获取数据 当不支持动态刷新的时候直接从本地缓存拿数据 public static NacosPropertySource getNacosPropertySource(String dataId,String group) {return NACOS_PROPERTY_SOURCE_REPOSITORY.get(getMapKey(dataId, group));}从服务端获取数据 NacosPropertySource build(String dataId, String group, String fileExtension,boolean isRefreshable) {//加载服务端配置MapString, Object p loadNacosData(dataId, group, fileExtension);//构建配置信息NacosPropertySource nacosPropertySource new NacosPropertySource(group, dataId,p, new Date(), isRefreshable);//保存本地缓存NacosPropertySourceRepository.collectNacosPropertySource(nacosPropertySource);return nacosPropertySource;}private ListPropertySource? loadNacosData(String dataId, String group,String fileExtension) {String data null;.....//获取服务信息data configService.getConfig(dataId, group, timeout);..... return Collections.emptyList();}Overridepublic String getConfig(String dataId, String group, long timeoutMs) throws NacosException {return getConfigInner(namespace, dataId, group, timeoutMs);}private String getConfigInner(String tenant, String dataId, String group, long timeoutMs) throws NacosException {group null2defaultGroup(group);ParamUtils.checkKeyParam(dataId, group);ConfigResponse cr new ConfigResponse();cr.setDataId(dataId);cr.setTenant(tenant);cr.setGroup(group);// 1.优先使用本地缓存配置String content LocalConfigInfoProcessor.getFailover(agent.getName(), dataId, group, tenant);if (content ! null) { LOGGER.warn([{}] [get-config] get failover ok, dataId{}, group{}, tenant{}, config{}, agent.getName(),dataId, group, tenant, ContentUtils.truncateContent(content));cr.setContent(content);configFilterChainManager.doFilter(null, cr);content cr.getContent();return content;}try {//2.委派给worker从远程服务器获取String[] ct worker.getServerConfig(dataId, group, tenant, timeoutMs);cr.setContent(ct[0]);configFilterChainManager.doFilter(null, cr);content cr.getContent();return content;} catch (NacosException ioe) {if (NacosException.NO_RIGHT ioe.getErrCode()) {throw ioe;}LOGGER.warn([{}] [get-config] get from server error, dataId{}, group{}, tenant{}, msg{},agent.getName(), dataId, group, tenant, ioe.toString());}LOGGER.warn([{}] [get-config] get snapshot ok, dataId{}, group{}, tenant{}, config{}, agent.getName(),dataId, group, tenant, ContentUtils.truncateContent(content));// 本地快照目录拿content LocalConfigInfoProcessor.getSnapshot(agent.getName(), dataId, group, tenant);cr.setContent(content);configFilterChainManager.doFilter(null, cr);content cr.getContent();return content;}本地缓存文件读取 public static String getFailover(String serverName, String dataId, String group, String tenant) {//从本地文件中获取File localPath getFailoverFile(serverName, dataId, group, tenant);if (!localPath.exists() || !localPath.isFile()) {return null;}try {//读文件return readFile(localPath);} catch (IOException ioe) {LOGGER.error([ serverName ] get failover error, localPath, ioe);return null;}}从Nacos服务端获取数据 public ConfigResponse getServerConfig(String dataId, String group, String tenant, long readTimeout, boolean notify)throws NacosException {//分组等于空设置默认分组 if (StringUtils.isBlank(group)) {group Constants.DEFAULT_GROUP;}//配置信息读取return this.agent.queryConfig(dataId, group, tenant, readTimeout, notify);}Override public ConfigResponse queryConfig(String dataId, String group, String tenant, long readTimeouts, boolean notify)throws NacosException {ConfigQueryRequest request ConfigQueryRequest.build(dataId, group, tenant);request.putHeader(NOTIFY_HEADER, String.valueOf(notify));RpcClient rpcClient getOneRunningClient();if (notify) {CacheData cacheData cacheMap.get().get(GroupKey.getKeyTenant(dataId, group, tenant));if (cacheData ! null) {rpcClient ensureRpcClient(String.valueOf(cacheData.getTaskId()));}}// 发送一个grpc请求读取配置信息ConfigQueryResponse response (ConfigQueryResponse) requestProxy(rpcClient, request, readTimeouts);ConfigResponse configResponse new ConfigResponse();...... } 服务端读取配置信息 ConfigQueryRequestHandler Override TpsControl(pointName ConfigQuery, parsers {ConfigQueryGroupKeyParser.class, ConfigQueryGroupParser.class}) Secured(action ActionTypes.READ, parser ConfigResourceParser.class) public ConfigQueryResponse handle(ConfigQueryRequest request, RequestMeta meta) throws NacosException {try {return getContext(request, meta, request.isNotify());} catch (Exception e) {return ConfigQueryResponse.buildFailResponse(ResponseCode.FAIL.getCode(), e.getMessage());}} 这里太长懒得贴 反正就是会先用groupKeydataidgroupnamespace 服务端对每一个配置文件都有服务端的内存缓存这里使用读写锁获取锁为了避免并发修改的情况 然后会判断当前模式是不是单机模式 并且不使用mysql 做数据存储的则从内置的数据库拿数据 如果配的是mysql 则从mysql中拿数据返回 缓存配置信息到本地 public static void collectNacosPropertySource(NacosPropertySource nacosPropertySource) {NACOS_PROPERTY_SOURCE_REPOSITORY.putIfAbsent(getMapKey(nacosPropertySource.getDataId(),nacosPropertySource.getGroup()), nacosPropertySource);}配置信息动态刷新 springboot自动注入的时候会去注入一个 NacosConfigAutoConfiguration 然后再这里面会注入一个 NacosContextRefresher进行数据的刷新 当spring启动的时候 会发送一个ApplicationReadyEvent事件而NacosContextRefresher会监听这个事件 Overridepublic void onApplicationEvent(ApplicationReadyEvent event) {// many Spring contextif (this.ready.compareAndSet(false, true)) {this.registerNacosListenersForApplications();}}private void registerNacosListenersForApplications() {//是否开启了刷新 配置文件中 spring.cloud.nacos.config.refresh-enabled true/false if (isRefreshEnabled()) {//开启了遍历 外部化配置的属性元for (NacosPropertySource propertySource : NacosPropertySourceRepository.getAll()) { //判断这个属性元是否开启了 Refreshableif (!propertySource.isRefreshable()) {continue;}String dataId propertySource.getDataId();//注册监听事件registerNacosListener(propertySource.getGroup(), dataId);}}}注册监听事件 当配置发生变更的时候会回调到这个监听事件中去发送一个刷新事件 具体怎么判断数据变更看上一张的safeNotifyListener方法 这个方法中会有一个innerReceive方法的调用最终会到这里 private void registerNacosListener(final String groupKey, final String dataKey) {String key NacosPropertySourceRepository.getMapKey(dataKey, groupKey);Listener listener listenerMap.computeIfAbsent(key,lst - new AbstractSharedListener() {//当NacosContextRefresher.getRefreshCount() ! 0 判断配置发生变化发生回调Overridepublic void innerReceive(String dataId, String group,String configInfo) {refreshCountIncrement();//添加刷新历史记录nacosRefreshHistory.addRefreshRecord(dataId, group, configInfo);// todo feature: support single refresh for listening//发布事件applicationContext.publishEvent(new RefreshEvent(this, null, Refresh Nacos config));if (log.isDebugEnabled()) {log.debug(String.format(Refresh Nacos config group%s,dataId%s,configInfo%s,group, dataId, configInfo));}}});try {configService.addListener(dataKey, groupKey, listener);}catch (NacosException e) {log.warn(String.format(register fail for nacos listener ,dataId[%s],group[%s], dataKey,groupKey), e);}}监听刷新事件 RefreshEventListener会监听到刷新事件进行处理 Overridepublic void onApplicationEvent(ApplicationEvent event) {if (event instanceof ApplicationReadyEvent) {handle((ApplicationReadyEvent) event);}else if (event instanceof RefreshEvent) {handle((RefreshEvent) event);}}public void handle(RefreshEvent event) {//是否就绪if (this.ready.get()) { // dont handle events before app is readylog.debug(Event received event.getEventDesc());SetString keys this.refresh.refresh();log.info(Refresh keys changed: keys);}}public synchronized SetString refresh() {SetString keys refreshEnvironment();//重新刷新beanthis.scope.refreshAll();return keys;}public synchronized SetString refreshEnvironment() {MapString, Object before extract(this.context.getEnvironment().getPropertySources());addConfigFilesToEnvironment();//得到发生变更的keySetString keys changes(before,extract(this.context.getEnvironment().getPropertySources())).keySet();//发布EnvironmentChange事件this.context.publishEvent(new EnvironmentChangeEvent(this.context, keys));return keys;}Environment变更事件监听 ConfigurationPropertiesRebinder 监听到事件重新进行数据的绑定 Overridepublic void onApplicationEvent(EnvironmentChangeEvent event) {if (this.applicationContext.equals(event.getSource())// Backwards compatible|| event.getKeys().equals(event.getSource())) {//数据绑定rebind();}}ManagedOperationpublic void rebind() {this.errors.clear();for (String name : this.beans.getBeanNames()) {rebind(name);}}ManagedOperationpublic boolean rebind(String name) {if (!this.beans.getBeanNames().contains(name)) {return false;}if (this.applicationContext ! null) {try {Object bean this.applicationContext.getBean(name);if (AopUtils.isAopProxy(bean)) {bean ProxyUtils.getTargetObject(bean);}if (bean ! null) {// TODO: determine a more general approach to fix this.// see https://github.com/spring-cloud/spring-cloud-commons/issues/571if (getNeverRefreshable().contains(bean.getClass().getName())) {return false; // ignore}//先卸载this.applicationContext.getAutowireCapableBeanFactory().destroyBean(bean);//重新初始化this.applicationContext.getAutowireCapableBeanFactory().initializeBean(bean, name);return true;}}catch (RuntimeException e) {this.errors.put(name, e);throw e;}catch (Exception e) {this.errors.put(name, e);throw new IllegalStateException(Cannot rebind to name, e);}}return false;}总结 springboot启动的时候怎么加载的nacos中的配置 1.springboot启动的时候会通过自动注入 将NacosPropertySourceLocator注入到bean容器中 然后会调用到locate方法中进行配置的读取 2.配置读取会先判断是否配置了自动刷新 如果没有配置则直接从缓存中读取 3.如果配置了自动刷新 会先从本地快照中读取 如果读取到了就返回并加入到本地缓存中 4.如果快照中也没有读取到 则通过grpc请求从服务端读取 从服务端读取的时候会先生成一个读写锁防止有问题 他会判断是集群还是单机启动 如果是单机启动并且没有使用mysql 则从内嵌的数据库里读取 如果是集群并且配置了mysql则从mysql 读取返回给客户端 5.如果从服务端也没读取到则从本地磁盘读取 怎么实现动态刷新配置 1.springboot启动的时候会通过自动注入 会注入一个NacosContextRefresher到bean容器中 这里面会注册一个监听器用来监听事件变更的一个回调 2.当服务端有配置变更之后会推送给客户端进行配置的修改并触发这个回调 3.然后回调中会触发一个刷新事件 4.当准备完毕之后会去发送一个spring中配置修改的一个事件 5.这个事件中会触发bean的重新绑定事件 实际上就是将老的bean给卸载将新的bean重新加载来实现配置的实时变更
http://www.pierceye.com/news/48380/

相关文章:

  • 电话网站源码wordpress 无法登录后台
  • 门户网站编辑联系方式深度科技有限公司
  • 建网站-湛江市网站后端都需要什么意思
  • 交易所网站建设教程wordpress长文章不显示评论框
  • 学校官方网站基因网站开发
  • 拖拽网站heritrix做网站
  • 南宁网站建设哪seo实战密码第四版电子书
  • 山东建站管理系统网站二维码制作
  • 设计单位在厦门什么网站centos 6 wordpress
  • 自己做抽奖网站违法吗搜索引擎营销怎么做
  • 石油化工建设网站江苏省建设工程招标网
  • 网站提交收录软件幼教资源网网站开发策划书
  • 预付做网站订金怎么做账seo运营工作内容
  • mvc网站开发之美Wordpress自建主题视频百度云下载
  • 做网站现在好弄么宁波网站建设xpckj
  • 生成短链接西安网站搜索引擎优化
  • 多少钱算网站好用的国外服务器
  • 郑州建站优化百度竞价排名是哪种方式
  • 网站的代运营双八网站建设
  • 网站建设 业务走下坡增城建设局网站
  • 网站托管服务 重庆问题不大工作室 网站
  • 怎样用文本建一个网站如何用word做简单的网站
  • 门户网站建设情况调研报告鞍山网站设计制作网站
  • 建网站无锡广州建设工程交易中心官网首页
  • 苏州网站建设极简幕枫网站开发毕业答辩
  • 商务网站建设 视频国外做油画的网站
  • 大型网站建设企业东莞常平二手房价最新消息
  • 邹平网站建设公司wordpress最近更新文章插件
  • 中介网站建设263邮箱登录入口官网
  • 国家工业和信息化部网站备案系统网站建设与管理 答案