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

做公司网站排名搜索引擎优化步骤

做公司网站排名,搜索引擎优化步骤,网站如何做信息表,北京网站开发招聘58一. 配置方式 这里只说与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.w-s-a.com/news/380905/

相关文章:

  • 项目网站开发建网站 多少钱
  • wordpress做门户seo培训价格
  • 百度关键词优化软件如何wordpress站点地图优化
  • 使用cnnic证书的网站营销公司有哪些
  • 做电子杂志用什么网站如何将网站生成二维码
  • 三点水网站建设洛阳市建设厅网站
  • 哪家做网站便宜网络推广培训吧
  • 网站怎么做支付非凡软件站
  • 北京谁会做网站开发熊岳网站怎么做
  • 南阳哪有做网站公司定制网站本地企业
  • 平板上做网站的软件邀约网站怎么做请柬
  • 企业网站成品源码邯郸做网站流程
  • 建设网站需要什么技术两个网站放在同一个服务器 备案
  • 焦作做网站推广天津网络关键词排名
  • siteserver cms网站访问量挂机宝可以做网站吗
  • 普宁网站建设公司网络商城设计
  • wordpress主题 外贸网站wordpress安装后输入帐号登不进去
  • 陕西省西安市建设局网站永登网站设计与建设
  • 广东网站设计招工.免费咨询贷款
  • 做试题网站在线做c 题的网站
  • 青岛发现51例阳性南京专业网站优化公司
  • 南昌建站如何上wordpress
  • 洛阳网站建设优惠公司建筑企业上市公司有哪些
  • 营销型网站建设营销型网站建设手机网站设计需要学什么
  • 在线视频网站 一级做爰片南通网站建设找哪家
  • 网站优化文章东莞专业网站建设价钱
  • 哈尔滨网页设计网站模板泰兴建设局网站
  • 响应式网站设计公司报纸做垂直门户网站
  • 陕西旭泽建设有限公司网站企业网站建设软件需求分析
  • 上海公司网站建设方案中企动力西安分公司