gpt4 book ai didi

没有 Spring Boot 的 Spring Cloud Config 客户端

转载 作者:IT老高 更新时间:2023-10-28 13:45:22 26 4
gpt4 key购买 nike

我们有一个现有的 Spring Web 应用程序作为 WAR 文件部署到 Amazon Elastic Beanstalk 中。目前,我们将属性文件加载为 http 资源,以便为我们提供属性占位符配置解析的单一来源。我正在研究用新的 spring 云配置服务器替换它,以便为我们提供 git 版本控制等的好处。

然而文档(http://cloud.spring.io/spring-cloud-config/spring-cloud-config.html)似乎只描述了一个 Spring Boot 客户端应用程序。是否可以在现有 Web 应用程序中设置 Spring Cloud Config Client?我是否需要手动设置 Bootstrap 父应用程序上下文等 - 有没有这样的例子?我们当前的 spring 配置是基于 XML 的。

最佳答案

引用:https://wenku.baidu.com/view/493cf9eba300a6c30d229f49.html

Root WebApplicationContextServlet WebApplicationContext 使用 Environment 并根据 spring 配置文件初始化 PropertySources。对于非 Spring Boot 应用程序,我们需要自定义这些以从 Config Server 获取属性,并在属性更改时刷新 bean。以下是使配置在 SpringMVC 中工作所需的更改。您还需要 spring.profile.active

的系统属性
  1. 创建一个 CustomBeanFactoryPostProcessor 并将所有 bean 定义上的 lazyInit 设置为 true 以延迟初始化所有 bean,即仅在请求时初始化 bean。

    @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<beanNames.length; i++){
    BeanDefinition beanDef = beanFactory.getBeanDefinition(beanNames[i]);
    beanDef.setLazyInit(true);
    beanDef.setScope("refresh");
    }
    }

    @Override
    public void setApplicationContext(ApplicationContext context)
    throws BeansException {
    applicationContext = context;
    }

    /**
    * Get a Spring bean by type.
    *
    * @param beanClass
    * @return
    */
    public static <T> T getBean(Class<T> 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. 创建一个自定义类,扩展 StandardServletEnvironment 并覆盖 initPropertySources 方法以加载其他 PropertySources(来自配置服务器)。

     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. 创建一个自定义的ApplicatonContextInitializer并重写initialize方法来设置custom Enviroment而不是StandardServletEnvironment.

    public class ConfigAppContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
    applicationContext.setEnvironment(new CloudEnvironment());
    }
    }
  4. 修改 web.xml 以将此自定义上下文初始化程序用于 application contextservlet context

    <servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>
    org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <init-param>
    <param-name>contextInitializerClasses</param-name>
    <param-value>com.my.context.ConfigAppContextInitializer</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
    </servlet>


    <servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
    </servlet-mapping>

    <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <context-param>
    <param-name>contextInitializerClasses</param-name>
    <param-value>com.my.context.ConfigAppContextInitializer</param-value>
    </context-param>

    <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
    </context-param>

  5. 要刷新创建了刷新端点的 bean,您还需要刷新 应用程序上下文

    @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();
}
}

关于没有 Spring Boot 的 Spring Cloud Config 客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28367425/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com