All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.javaclub.configcenter.spring.config.PropertySourcesProcessor Maven / Gradle / Ivy

The newest version!
package com.github.javaclub.configcenter.spring.config;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.Ordered;
import org.springframework.core.PriorityOrdered;
import org.springframework.core.env.CompositePropertySource;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;

import com.github.javaclub.configcenter.ConfigServerConstants.BootConfig;
import com.github.javaclub.configcenter.client.AppConfig;
import com.github.javaclub.configcenter.client.ConfigService;
import com.github.javaclub.configcenter.spring.property.AutoUpdateConfigChangeListener;
import com.github.javaclub.configcenter.spring.utils.SpringInjector;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import com.google.common.eventbus.EventBus;

/**
 * ConfigCenter Property Sources processor for Spring Annotation Based
 * Application. 
*
* * The reason why PropertySourcesProcessor implements * {@link BeanFactoryPostProcessor} instead of * {@link org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor} * is that lower versions of Spring (e.g. 3.1.1) doesn't support registering * BeanDefinitionRegistryPostProcessor in ImportBeanDefinitionRegistrar - * {@link com.github.javaclub.configcenter.spring.annotation.ConfigServerRegistrar} * */ public class PropertySourcesProcessor implements BeanFactoryPostProcessor, EnvironmentAware, PriorityOrdered { private static final Multimap NAMESPACE_NAMES = LinkedHashMultimap.create(); private static final Set AUTO_UPDATE_INITIALIZED_BEAN_FACTORIES = Sets.newConcurrentHashSet(); protected final EventBus eventBus = SpringInjector.getInstance(EventBus.class); protected final ConfigPropertySourceFactory configPropertySourceFactory = SpringInjector.getInstance(ConfigPropertySourceFactory.class); private ConfigurableEnvironment environment; public static boolean addNamespaces(Collection namespaces, int order) { return NAMESPACE_NAMES.putAll(order, namespaces); } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { eventBus.register(this); initializePropertySources(); initializeAutoUpdatePropertiesFeature(beanFactory); } private void initializePropertySources() { if (environment.getPropertySources().contains(BootConfig.CONFIGSERVER_PROPERTY_SOURCE_NAME)) { // already initialized return; } CompositePropertySource composite = new CompositePropertySource(BootConfig.CONFIGSERVER_PROPERTY_SOURCE_NAME); // sort by order asc ImmutableSortedSet orders = ImmutableSortedSet.copyOf(NAMESPACE_NAMES.keySet()); Iterator iterator = orders.iterator(); while (iterator.hasNext()) { int order = iterator.next(); for (String namespace : NAMESPACE_NAMES.get(order)) { AppConfig config = ConfigService.getAppConfig(); composite.addPropertySource(configPropertySourceFactory.getConfigPropertySource(namespace, config)); } } // clean up NAMESPACE_NAMES.clear(); // add after the bootstrap property source or to the first if (environment.getPropertySources().contains(BootConfig.CONFIGSERVER_BOOTSTRAP_PROPERTY_SOURCE_NAME)) { // ensure ConfigserverBootstrapPropertySources is still the first ensureBootstrapPropertyPrecedence(environment); environment.getPropertySources().addAfter(BootConfig.CONFIGSERVER_BOOTSTRAP_PROPERTY_SOURCE_NAME, composite); } else { environment.getPropertySources().addFirst(composite); } } private void ensureBootstrapPropertyPrecedence(ConfigurableEnvironment environment) { MutablePropertySources propertySources = environment.getPropertySources(); PropertySource bootstrapPropertySource = propertySources.get(BootConfig.CONFIGSERVER_BOOTSTRAP_PROPERTY_SOURCE_NAME); // not exists or already in the first place if (bootstrapPropertySource == null || propertySources.precedenceOf(bootstrapPropertySource) == 0) { return; } propertySources.remove(BootConfig.CONFIGSERVER_BOOTSTRAP_PROPERTY_SOURCE_NAME); propertySources.addFirst(bootstrapPropertySource); } private void initializeAutoUpdatePropertiesFeature(ConfigurableListableBeanFactory beanFactory) { if (!AUTO_UPDATE_INITIALIZED_BEAN_FACTORIES.add(beanFactory)) { return; } AutoUpdateConfigChangeListener autoUpdateConfigChangeListener = new AutoUpdateConfigChangeListener(environment, beanFactory); List configPropertySources = configPropertySourceFactory.getAllConfigPropertySources(); for (ConfigPropertySource configPropertySource : configPropertySources) { configPropertySource.addChangeListener(autoUpdateConfigChangeListener); } } @Override public void setEnvironment(Environment environment) { // it is safe enough to cast as all known environment is derived from ConfigurableEnvironment this.environment = (ConfigurableEnvironment) environment; } @Override public int getOrder() { // make it as early as possible return Ordered.HIGHEST_PRECEDENCE; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy