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

网站搭建设计金融网站建设成功案例

网站搭建设计,金融网站建设成功案例,网站如何做浏览量,怎样做简单的网站一. 配置方式 这里只说与Spring集成后的配置方式#xff0c;这也是项目中主要使用的方式 Apollo 在属性上直接加value注解#xff0c;这个属性就会随着配置的更改动态更新类实现ConfigChangeListener#xff0c;在类中方法上ApolloConfigChangeListener注解#xff0c;注解…一. 配置方式 这里只说与Spring集成后的配置方式这也是项目中主要使用的方式 Apollo 在属性上直接加value注解这个属性就会随着配置的更改动态更新类实现ConfigChangeListener在类中方法上ApolloConfigChangeListener注解注解在方法上监控配置的变化配置变化后会自定义方法来达到动态刷新bean的目的 Nacos Nacos无需任何配置即可对有ConfigurationProperties注解的类进行配置的动态刷新Nacos自2022.0.0.0-RC1版本后可通过spring.cloud.nacos.config.refresh-bahavior指定刷新模式默认是all_beans(刷新所有bean)可选specific_bean (只刷新有配置值更改的bean) 优劣对比 先说结论二者的优劣势对比具体的原理机制等相对复杂放后文详细讲解 Apollo 优势 提供出listener使用者可灵活自行定制bean的刷新方式 劣势 Apollo除Value注解外不提供动态刷新的默认实现方案而Value注解平常用的较少就比较鸡肋用户想要用ConfigurationProperties配置类的方式动态刷新必须要自己去实现 Nacos 优势 有动态刷新的默认实现用户可直接使用且从2022.0.0.0-RC1版本后可自选bean的刷新模式 劣势 不管选用哪种nacos的刷新方案RefreshScope域都会全刷新触发RefreshScopeRefreshedEvent事件的发布如eureka会订阅该事件并于该事件发布时触发eurekaClient的重新注册若是配置热更新的比较频繁那么会触发eurekaClient的频繁重注册 最终抉择 动态热更新的时候肯定是更新哪个配置那么只将与这个配置对应的bean进行更新最好若是用的nacos,那么可选用2022.0.0.0-RC1版本bean的刷新行为选用specific_bean指定刷新若是用的Apollo需自己实现也可参考nacos中的SmartConfigurationPropertiesRebinder类进行自实现配置动态刷新后建议还是要发布下RefreshScopeRefreshedEvent事件使得依赖该事件发布的其他组件在配置刷新后可重新配置与该之相关的的内容避免真的更改了例如eureka的配置后eureka因不能重注册client导致的配置无法生效的问题。这里比较坑的地方就是springcloud没有提供一种机制可监听自己的配置更改及事件发布对应着触发事件进行导致只是更改了用户自定义的一些配置也触发了eureka客户端重注册这种看似风马牛不相及的行为出现 动态刷新机制 这里只以nacos为例重点讲解服务通过监听器拿到配置变更之后的流程Apollo在自行实现时也可参考此流程 NacosContextRefresher监听ApplicationReadyEvent事件会在应用准备启动时间发布后注册NacosListener在注册时会实现listener的innerReceive方法在配置变更后会通知到该方法该方法会触发事件的发布 applicationContext.publishEvent(new RefreshEvent(this, null, Refresh Nacos config)); Overridepublic void onApplicationEvent(ApplicationReadyEvent event) {// many Spring contextif (this.ready.compareAndSet(false, true)) {this.registerNacosListenersForApplications();}}/*** register Nacos Listeners.*/private void registerNacosListenersForApplications() {if (isRefreshEnabled()) {for (NacosPropertySource propertySource : NacosPropertySourceRepository.getAll()) {if (!propertySource.isRefreshable()) {continue;}String dataId propertySource.getDataId();registerNacosListener(propertySource.getGroup(), dataId);}}}private void registerNacosListener(final String groupKey, final String dataKey) {String key NacosPropertySourceRepository.getMapKey(dataKey, groupKey);Listener listener listenerMap.computeIfAbsent(key,lst - new AbstractSharedListener() {Overridepublic void innerReceive(String dataId, String group,String configInfo) {refreshCountIncrement();nacosRefreshHistory.addRefreshRecord(dataId, group, configInfo);// 这里发布RefreshEvent事件用以刷新bean实例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);log.info([Nacos Config] Listening config: dataId{}, group{}, dataKey,groupKey);}catch (NacosException e) {log.warn(String.format(register fail for nacos listener ,dataId[%s],group[%s], dataKey,groupKey), e);}}bean刷新的处理在订阅了该事件的RefreshEventListener中 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);}}程序流转到ContextRefresher的refresh方法中 public synchronized SetString refresh() {// 刷新环境变量SetString keys refreshEnvironment();// 刷新RefreshScope内的所有缓存this.scope.refreshAll();return keys;}我们追溯到refreshEnvironment方法内其内的重点有两处一处是在这里获取到了配置中心更改的值另一处则将更改的值放入EnvironmentChangeEvent事件中进行发布 public synchronized SetString refreshEnvironment() {MapString, Object before extract(this.context.getEnvironment().getPropertySources());addConfigFilesToEnvironment();SetString keys changes(before,extract(this.context.getEnvironment().getPropertySources())).keySet();this.context.publishEvent(new EnvironmentChangeEvent(this.context, keys));return keys;我们找到订阅EnvironmentChangeEvent该事件的类SmartConfigurationPropertiesRebinder,跟到onApplicationEvent方法该方法会根据refreshBehavior选择对应的bean刷新方式 Overridepublic void onApplicationEvent(EnvironmentChangeEvent event) {if (this.applicationContext.equals(event.getSource())// Backwards compatible|| event.getKeys().equals(event.getSource())) {switch (refreshBehavior) {case SPECIFIC_BEAN - rebindSpecificBean(event);default - rebind();}}}我们先跟踪到默认处理方案rebind方法中该方法在当前类中的父类ConfigurationPropertiesRebinder中实现 ManagedOperationpublic void rebind() {this.errors.clear();for (String name : this.beans.getBeanNames()) {rebind(name);}}跟踪到rebind(name)方法可以看到在本方法中对指定name的bean进行destory(销毁)并且重新initialize(实例化) 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) {if (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;}到这里我们就知道原来在这里进行了bean的重新实例化那么重新实例化的这些bean是什么bean呢beans变量是关键线索beans对应着ConfigurationPropertiesBeans类当前类中注入了ConfigurationPropertiesBeans对象我们跟踪到该对象看该类的注释可知该类是当前相聚中所有包含ConfigurationProperties注解的bean的集合类 /*** Collects references to codeConfigurationProperties/code beans in the context and* its parent.**/也就是说在默认的情况下随着配置的变更会导致所有包含ConfigurationProperties注解的bean重新绑定接下来我们回到第6步进入SmartConfigurationPropertiesRebinder类的rebindSpecificBean(event)方法中 private void rebindSpecificBean(EnvironmentChangeEvent event) {SetString refreshedSet new HashSet();beanMap.forEach((name, bean) - event.getKeys().forEach(changeKey - {String prefix AnnotationUtils.getValue(bean.getAnnotation()).toString();// prevent multiple refresh one ConfigurationPropertiesBean.if (changeKey.startsWith(prefix) refreshedSet.add(name)) {rebind(name);}}));}可以看出该方法主要做的是事情是遍历beanMap拿到对应的bean及其对应的前缀(etc: spring.xxx)然后再拿到变更的key若匹配则才对当前bean进行更新以此方法实现了只更新特定的bean而不会像第10步一样全部更新可以看出当前beanMap是核心这个beanMap怎么得到的呢可以看出它是在当前类构造函数中就已填充了 public SmartConfigurationPropertiesRebinder(ConfigurationPropertiesBeans beans) {super(beans);fillBeanMap(beans);}SuppressWarnings(unchecked)private void fillBeanMap(ConfigurationPropertiesBeans beans) {this.beanMap new HashMap();Field field ReflectionUtils.findField(beans.getClass(), beans);if (field ! null) {field.setAccessible(true);this.beanMap.putAll((MapString, ConfigurationPropertiesBean) Optional.ofNullable(ReflectionUtils.getField(field, beans)).orElse(Collections.emptyMap()));}}可看出它获取到父类的beans字段所对应值而后采用反射最终取出ConfigurationPropertiesBeans类中的beans对象放入当前的beanMap中至此对应第4步中的refreshEnvironment()方法执行完毕接下来我们跟踪进入到RefreshScope的refreshAll方法中 ManagedOperation(description Dispose of the current instance of all beans in this scope and force a refresh on next method execution.)public void refreshAll() {super.destroy();this.context.publishEvent(new RefreshScopeRefreshedEvent());}我们跟踪进GenericScope的destory方法中 Overridepublic void destroy() {ListThrowable errors new ArrayListThrowable();CollectionBeanLifecycleWrapper wrappers this.cache.clear();for (BeanLifecycleWrapper wrapper : wrappers) {try {Lock lock this.locks.get(wrapper.getName()).writeLock();lock.lock();try {wrapper.destroy();}finally {lock.unlock();}}catch (RuntimeException e) {errors.add(e);}}if (!errors.isEmpty()) {throw wrapIfNecessary(errors.get(0));}this.errors.clear();}我们看到destroy方法会对当前的域缓存进行清空若清空时返回数据则会对缓存对应的bean进行destroy之后会有其他地方对bean重新创建这里也就是会对所有属于RefreshScope域的对象进行的重新实例化在destroy执行后会发布RefreshScopeRefreshedEvent事件我们可以看查找所有订阅该事件的类就可知有哪些组件会受此影响了
文章转载自:
http://www.morning.yckwt.cn.gov.cn.yckwt.cn
http://www.morning.gfqj.cn.gov.cn.gfqj.cn
http://www.morning.hqrr.cn.gov.cn.hqrr.cn
http://www.morning.sfdky.cn.gov.cn.sfdky.cn
http://www.morning.ghxkm.cn.gov.cn.ghxkm.cn
http://www.morning.bsrp.cn.gov.cn.bsrp.cn
http://www.morning.zxfr.cn.gov.cn.zxfr.cn
http://www.morning.kongpie.com.gov.cn.kongpie.com
http://www.morning.tfbpz.cn.gov.cn.tfbpz.cn
http://www.morning.fqpgf.cn.gov.cn.fqpgf.cn
http://www.morning.bnqcm.cn.gov.cn.bnqcm.cn
http://www.morning.jlmrx.cn.gov.cn.jlmrx.cn
http://www.morning.nzfqw.cn.gov.cn.nzfqw.cn
http://www.morning.yqwsd.cn.gov.cn.yqwsd.cn
http://www.morning.cznsq.cn.gov.cn.cznsq.cn
http://www.morning.wtrjq.cn.gov.cn.wtrjq.cn
http://www.morning.zlgbx.cn.gov.cn.zlgbx.cn
http://www.morning.fplqh.cn.gov.cn.fplqh.cn
http://www.morning.qlbmc.cn.gov.cn.qlbmc.cn
http://www.morning.xxrwp.cn.gov.cn.xxrwp.cn
http://www.morning.cfpq.cn.gov.cn.cfpq.cn
http://www.morning.yznsx.cn.gov.cn.yznsx.cn
http://www.morning.kwqwp.cn.gov.cn.kwqwp.cn
http://www.morning.trpq.cn.gov.cn.trpq.cn
http://www.morning.hwprz.cn.gov.cn.hwprz.cn
http://www.morning.rckmz.cn.gov.cn.rckmz.cn
http://www.morning.btwlp.cn.gov.cn.btwlp.cn
http://www.morning.djbhz.cn.gov.cn.djbhz.cn
http://www.morning.wcjk.cn.gov.cn.wcjk.cn
http://www.morning.kzbpx.cn.gov.cn.kzbpx.cn
http://www.morning.lcbnb.cn.gov.cn.lcbnb.cn
http://www.morning.nkqxb.cn.gov.cn.nkqxb.cn
http://www.morning.mbbgk.com.gov.cn.mbbgk.com
http://www.morning.rxcqt.cn.gov.cn.rxcqt.cn
http://www.morning.jhwwr.cn.gov.cn.jhwwr.cn
http://www.morning.hhqjf.cn.gov.cn.hhqjf.cn
http://www.morning.hhfqk.cn.gov.cn.hhfqk.cn
http://www.morning.cwrpd.cn.gov.cn.cwrpd.cn
http://www.morning.wxfjx.cn.gov.cn.wxfjx.cn
http://www.morning.rkfwr.cn.gov.cn.rkfwr.cn
http://www.morning.c-ae.cn.gov.cn.c-ae.cn
http://www.morning.ctbr.cn.gov.cn.ctbr.cn
http://www.morning.rgnp.cn.gov.cn.rgnp.cn
http://www.morning.pfjbn.cn.gov.cn.pfjbn.cn
http://www.morning.rjmd.cn.gov.cn.rjmd.cn
http://www.morning.zwzlf.cn.gov.cn.zwzlf.cn
http://www.morning.qtkdn.cn.gov.cn.qtkdn.cn
http://www.morning.jzfxk.cn.gov.cn.jzfxk.cn
http://www.morning.prznc.cn.gov.cn.prznc.cn
http://www.morning.dfkby.cn.gov.cn.dfkby.cn
http://www.morning.pcbfl.cn.gov.cn.pcbfl.cn
http://www.morning.btblm.cn.gov.cn.btblm.cn
http://www.morning.qttft.cn.gov.cn.qttft.cn
http://www.morning.sjli222.cn.gov.cn.sjli222.cn
http://www.morning.gcthj.cn.gov.cn.gcthj.cn
http://www.morning.kcfnp.cn.gov.cn.kcfnp.cn
http://www.morning.dtnyl.cn.gov.cn.dtnyl.cn
http://www.morning.knmp.cn.gov.cn.knmp.cn
http://www.morning.smdkk.cn.gov.cn.smdkk.cn
http://www.morning.nqgds.cn.gov.cn.nqgds.cn
http://www.morning.bzfwn.cn.gov.cn.bzfwn.cn
http://www.morning.hcwjls.com.gov.cn.hcwjls.com
http://www.morning.ptzf.cn.gov.cn.ptzf.cn
http://www.morning.kphsp.cn.gov.cn.kphsp.cn
http://www.morning.zylzk.cn.gov.cn.zylzk.cn
http://www.morning.bpmfl.cn.gov.cn.bpmfl.cn
http://www.morning.fdrch.cn.gov.cn.fdrch.cn
http://www.morning.nwnbq.cn.gov.cn.nwnbq.cn
http://www.morning.pthmn.cn.gov.cn.pthmn.cn
http://www.morning.rpgdd.cn.gov.cn.rpgdd.cn
http://www.morning.cpfbg.cn.gov.cn.cpfbg.cn
http://www.morning.mjwnc.cn.gov.cn.mjwnc.cn
http://www.morning.flxgx.cn.gov.cn.flxgx.cn
http://www.morning.gnbfj.cn.gov.cn.gnbfj.cn
http://www.morning.ymqfx.cn.gov.cn.ymqfx.cn
http://www.morning.qfths.cn.gov.cn.qfths.cn
http://www.morning.epeij.cn.gov.cn.epeij.cn
http://www.morning.nlcw.cn.gov.cn.nlcw.cn
http://www.morning.fblkr.cn.gov.cn.fblkr.cn
http://www.morning.bkryb.cn.gov.cn.bkryb.cn
http://www.tj-hxxt.cn/news/279645.html

相关文章:

  • 如何做网站站内搜索wordpress 图片放大
  • linux建设网站制作网站管理系统
  • 创建一个网站要多少钱东道设计公司难进吗
  • 益阳网站建设详细教程电子商务企业网站建设实训报告
  • 里水九江网站建设想做无货源电商怎么入手
  • 有效的网站优化网站建设基础百度百科
  • 深圳网站建设 利科技织梦网站首页空白
  • 网站建设策划书提纲百度竞价规则
  • 招远 两学一做 网站类似WordPress的Python
  • 新动力网站建设成都动力无限 网站 差
  • 网站开发设计内容wordpress图片集
  • 抓取wordpress站点用户公司网站一般多少钱
  • 多少钱一个网站dw网页制作源代码
  • 什么叫做营销型网站邯郸网站建设小霖
  • 看设计案例的有哪些网站网站模板 自适应
  • 做投票的网站苏州姑苏区网站建设
  • 视频网站logo怎么做做留言的网站
  • 宁波网站建设公司推荐哪家淘宝店铺推广渠道有哪些
  • 做视频网站视频短片呼和浩特网站网站建设
  • 盐城网站开发怎么样如何优化网站图片
  • 山东做网站公司北京建设网站合同下载
  • 宁波手机建站模板wordpress图片介绍
  • 攀枝花建设工程质量监督站投诉网站网站建设定做
  • 浙江天奥建设集团网站seo关键词排名优化报价
  • 建站平台入口重庆报考网
  • 郑州做网站公司汉狮网钢材公司网站建设
  • 自己做网站难吗网站建设公司 南宁
  • 门户网站建设依据桂林小学网站建设
  • 网站内链技巧邯郸营销网站建设公司
  • 网站流量 用什么表示wordpress免费汽车配件企业主题