Spring Cloud Config Client Without Spring Boot

前端 未结 5 1708
猫巷女王i
猫巷女王i 2020-12-02 10:23

We have an existing spring web app deployed as a WAR file into Amazon Elastic Beanstalk. Currently we load properties files as http resources to give us a single source of p

5条回答
  •  野趣味
    野趣味 (楼主)
    2020-12-02 11:19

    Refrenced: https://wenku.baidu.com/view/493cf9eba300a6c30d229f49.html

    Root WebApplicationContext and the Servlet WebApplicationContext uses Environment and initializes PropertySources based on the spring profile. For non-spring boot apps, we need to customize these to get the properties from Config Server and to refresh the beans whenever there is a property change. Below are the changes that needs to happen to get the config working in SpringMVC. You will also need a system property for spring.profile.active

    1. Create a CustomBeanFactoryPostProcessor and set lazyInit on all bean definitions to true to initialize all bean lazily i.e. beans are initialized only upon a request.

      @Component
      public class AddRefreshScopeProcessor implements BeanFactoryPostProcessor, ApplicationContextAware {
      
      private static ApplicationContext applicationContext;
      
      @SuppressWarnings("unchecked")
      @Override
      public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
      
          String[] beanNames = applicationContext.getBeanDefinitionNames();
          for(int i=0; i T getBean(Class beanClass) {
          return applicationContext.getBean(beanClass);
      }
      
      /**
       * Get a Spring bean by name.
       * 
       * @param beanName
       * @return
       */
      public static Object getBean(String beanName) {
          return applicationContext.getBean(beanName);
        }
      }
      
    2. Create a custom class extending StandardServletEnvironment and overriding the initPropertySources method to load additional PropertySources (from config server).

       public class CloudEnvironment extends StandardServletEnvironment {
      
        @Override
          public void initPropertySources(ServletContext servletContext, ServletConfig servletConfig) {
       super.initPropertySources(servletContext,servletConfig);
       customizePropertySources(this.getPropertySources());
         }
      
      @Override
        protected void customizePropertySources(MutablePropertySources propertySources) {
          super.customizePropertySources(propertySources);
          try {
            PropertySource source = initConfigServicePropertySourceLocator(this);
            propertySources.addLast(source);
      
          } catch (
      
          Exception ex) {
            ex.printStackTrace();
          }
        }
      
        private PropertySource initConfigServicePropertySourceLocator(Environment environment) {
      
          ConfigClientProperties configClientProperties = new ConfigClientProperties(environment);
          configClientProperties.setUri("http://localhost:8888");
          configClientProperties.setProfile("dev");
          configClientProperties.setLabel("master");
          configClientProperties.setName("YourApplicationName");
      
          System.out.println("##################### will load the client configuration");
          System.out.println(configClientProperties);
      
          ConfigServicePropertySourceLocator configServicePropertySourceLocator =
              new ConfigServicePropertySourceLocator(configClientProperties);
      
          return configServicePropertySourceLocator.locate(environment);
          }
      
        }
      
    3. Create a custom ApplicatonContextInitializer and override the initialize method to set the custom Enviroment instead of the StandardServletEnvironment.

      public class ConfigAppContextInitializer implements ApplicationContextInitializer {
      
      @Override
      public void initialize(ConfigurableApplicationContext applicationContext) {
          applicationContext.setEnvironment(new CloudEnvironment());
        }
      }
      
    4. Modify web.xml to use this custom context initializer for both application context and servlet context.

      
          dispatcher
              
                  org.springframework.web.servlet.DispatcherServlet
              
          
              contextInitializerClasses
              com.my.context.ConfigAppContextInitializer
          
          1
      
      
      
      
          dispatcher
          /
      
      
      
       org.springframework.web.context.ContextLoaderListener
      
      
      
          contextInitializerClasses
          com.my.context.ConfigAppContextInitializer
      
      
      
          contextConfigLocation
          /WEB-INF/dispatcher-servlet.xml
      
      

    5. To refresh the beans created a refresh endpoint you will also need to refresh the application Context.

      @Controller
      public class RefreshController {
      
      @Autowired
      private RefreshAppplicationContext refreshAppplicationContext;
      
      @Autowired
      private RefreshScope refreshScope;
      
      @RequestMapping(path = "/refreshall", method = RequestMethod.GET)
      public String refresh() {
          refreshScope.refreshAll();
          refreshAppplicationContext.refreshctx();
          return "Refreshed";
      }
      }
      

    RefreshAppplicationContext.java

    @Component
    public class RefreshAppplicationContext implements ApplicationContextAware {
    
        private ApplicationContext applicationContext;
        public void setApplicationContext(ApplicationContext applicationContext) {
            this.applicationContext = applicationContext;
        }
    
    
        public void refreshctx(){
            ((XmlWebApplicationContext)(applicationContext)).refresh();
        }
    }
    

提交回复
热议问题