关于apollo刷新带有@ConfigurationProperties注解的注入对象的解决办法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于apollo刷新带有@ConfigurationProperties注解的注入对象的解决办法相关的知识,希望对你有一定的参考价值。

参考技术A apollo动态刷新,应用在@value这种注入方式的属性没有问题,但是如果使用@ConfigurationProperties注解的bean,动态刷新就不好使了,会注入不到的。

@ConfigurationProperties 如果需要在Apollo配置变化时自动更新注入的值,需要配合使用 EnvironmentChangeEvent 或 RefreshScope 。

比如我们自定义的某个bean,也有spring cloud gateway 注入routeDefination 那样嵌死在源码里头,我们都可以使用官网给出的方式去解决。

https://www.apolloconfig.com/#/zh/usage/java-sdk-user-guide?id=_3223-configurationproperties%e4%bd%bf%e7%94%a8%e6%96%b9%e5%bc%8f

有两种方式:

https://gitee.com/apolloconfig/apollo-use-cases/blob/master/spring-cloud-zuul/src/main/java/com/ctrip/framework/apollo/use/cases/spring/cloud/zuul/ZuulPropertiesRefresher.java


https://gitee.com/apolloconfig/apollo/blob/1.8.2/apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/springBootDemo/refresh/SpringBootApolloRefreshConfig.java

vue-apollo awsappsync - 刷新凭证

【中文标题】vue-apollo awsappsync - 刷新凭证【英文标题】:vue-apollo awsappsync - refresh credentials 【发布时间】:2019-06-01 21:16:14 【问题描述】:

我正在使用带有 AWSAppSyncClient 的 vue-apollo。我已按照 Vue 的文档 - https://github.com/awslabs/aws-mobile-appsync-sdk-js 进行操作。我的要求是用户应该能够订阅 appsync。这是 main.js 代码。

import './bootstrap';
import router from './routes';
import store from './store';
import App from './components/templates/App';
import AWSAppSyncClient from 'aws-appsync';
import VueApollo from "vue-apollo";

const config = 
  url: process.env.MIX_APPSYNC_URL,
  region: process.env.MIX_APPSYNC_REGION,
  auth: 
    type: process.env.MIX_APPSYNC_TYPE,
    credentials: 
      accessKeyId: "temporary access key goes here",
      secretAccessKey: "temporary secret access key goes here",
      sessionToken: "session token goes here"
    
  ,
;

在用户使用 aws cognito 验证成功登录后,我得到了“凭据”部分。

const options = 
  defaultOptions: 
    watchQuery: 
      fetchPolicy: 'cache-and-network',
    
  


// Create the apollo client
const apolloClient = new AWSAppSyncClient(config, options);

//The provider holds the Apollo client instances that can then be used by all the child components.
const apolloProvider = new VueApollo(
  defaultClient: apolloClient,
);

var vm = new Vue(
  el:"#dashboardapp",
  router:router,
  apolloProvider:apolloProvider,
  store:store,
  components:  App ,
  template: '<App/>',
  data() 
    return 

    
  ,
);

上述设置工作正常。用户可以登录。在 cognito 验证用户后,它会发送临时凭证(访问密钥、密钥、会话令牌)。使用临时凭据,我可以通过 vue-apollo 订阅 aws appsync。但是,凭证的有效期仅为 1 小时。所以我需要更新凭据并保留订阅部分以获取实时数据。但我不知道该怎么做。我浏览了文档,但找不到任何特定于我的案例的内容。

我需要从“vm”的子组件或 vuex 商店更新凭据。我已经更新了凭据。我只是不知道如何将其传递给“AWSAppSyncClient”以及如何使用更新的凭证重新订阅。我也不想重新加载页面。它应该在不重新加载页面的情况下更新凭据。希望以前有人会这样做吗?

【问题讨论】:

【参考方案1】:

我对我的代码做了一些更改,现在我能够实现我想要的。这是我所做的更改,以防有人做同样的事情。

首先将 apollo 客户端加载为空白 - 意味着 main.js 文件中没有 awsappsyncclient。

import './bootstrap';
import router from './routes';
import store from './store';
import App from './components/templates/App';
import VueApollo from "vue-apollo";

// Create the apollo client
const apolloClient = '';

//The provider holds the Apollo client instances that can then be used by all the child components.
const apolloProvider = new VueApollo(
  defaultClient: apolloClient,
);

var vm = new Vue(
  el:"#dashboardapp",
  router:router,
  apolloProvider:apolloProvider,
  store:store,
  components:  App ,
  template: '<App/>',
  data() 
    return 

    
  ,
);

然后我从子组件创建智能订阅。临时凭据过期后,我将生成新凭据并在 vuex 存储中进行更新。基于更改,我将放弃旧的智能订阅并创建新的智能订阅。

这是子组件代码。

<template>
  <div class="status-frame">
   <!-- relevant code goes here -->
  </div>
</template>

<script>
import gql from 'graphql-tag';
import AWSAppSyncClient from 'aws-appsync';
import VueApollo from "vue-apollo";

export default 
  data () 
    return 

    
  ,
  methods: 
    timelineSubscribe() 
      if(this.$parent.$apolloProvider.clients[1]) 
        delete this.$parent.$apolloProvider.clients[1];
        this.$apollo.subscriptions.subscribeToNewNotification.stop();
      
      const config = 
        url: process.env.MIX_APPSYNC_URL,
        region: process.env.MIX_APPSYNC_REGION,
        auth: 
          type: process.env.MIX_APPSYNC_TYPE,
          credentials: 
            accessKeyId: this.appsyncObj.accessKeyId,
            secretAccessKey: this.appsyncObj.secretAccessKey,
            sessionToken: this.appsyncObj.sessionToken
          
        ,
      ;

      const options = 
        defaultOptions: 
          watchQuery: 
            fetchPolicy: 'cache-and-network',
          
        
       

      // Create the apollo client
      const apolloClient = new AWSAppSyncClient(config, options);

      // add apolloClient to a new index in apolloProvider. 
      this.$parent.$apolloProvider.clients[1] = apolloClient;

      console.log(this.$apollo.provider.clients);

      this.$apollo.addSmartSubscription('subscribeToAnything', 
        client: '1',
        query: gql`subscription subscribeToAnything ($accountId: String!) 
          subscribeToAnything(accountId: $accountId) 
           // required fields goes here
          
        `,

        // Reactive variables
        variables() 
        // This works just like regular queries
        // and will re-subscribe with the right variables
        // each time the values change
          return 
            accountId: 'account_id goes here',
          
        ,
       // Result hook
       result(data) 
         console.log(data);
       ,
       skip () 
         return false;
       
      );
    
  ,
  computed: 
    appsyncObj() 
      return this.$store.getters['profile/appsyncObj']; // get from vuex store
    
  ,
  watch: 
    'appsyncObj' () 
      this.timelineSubscribe(); // each time appsyncObj changes, it will call  this method and resubscribe with new credentials.
    
  ,

我在登录后和获得新凭据后更新了 appsyncObj 的 vuex 存储。但是,我没有在此处添加该代码。

【讨论】:

以上是关于关于apollo刷新带有@ConfigurationProperties注解的注入对象的解决办法的主要内容,如果未能解决你的问题,请参考以下文章

如何在本地网络上部署带有 apollo 客户端和 apollo-server 后端的 React 应用程序

带有命名空间查询的 Apollo Client 3.0 缓存

如何使用带有 react-apollo 的模拟数据进行测试

Apollo配置中心动态刷新日志级别

使用 apollo-client + firebase auth 刷新令牌

在 Angular Apollo Graphql 中访问突变结果