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

com.ctrip.framework.apollo.spring.config.PropertySourcesProcessor Maven / Gradle / Ivy

The newest version!
package com.ctrip.framework.apollo.spring.config;

import com.ctrip.framework.apollo.build.ApolloInjector;
import com.ctrip.framework.apollo.spring.property.AutoUpdateConfigChangeListener;
import com.ctrip.framework.apollo.spring.util.SpringInjector;
import com.ctrip.framework.apollo.util.ConfigUtil;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;

import com.ctrip.framework.apollo.Config;
import com.ctrip.framework.apollo.ConfigService;

import com.google.common.collect.Sets;
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 java.util.Collection;
import java.util.Iterator;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;

/**
 * Apollo 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.ctrip.framework.apollo.spring.annotation.ApolloConfigRegistrar} * * @author Jason Song([email protected]) */ 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(); private final ConfigPropertySourceFactory configPropertySourceFactory = SpringInjector .getInstance(ConfigPropertySourceFactory.class); private final ConfigUtil configUtil = ApolloInjector.getInstance(ConfigUtil.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 { initializePropertySources(); initializeAutoUpdatePropertiesFeature(beanFactory); } private void initializePropertySources() { if (environment.getPropertySources().contains(PropertySourcesConstants.APOLLO_PROPERTY_SOURCE_NAME)) { //already initialized return; } CompositePropertySource composite = new CompositePropertySource(PropertySourcesConstants.APOLLO_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)) { Config config = ConfigService.getConfig(namespace); 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(PropertySourcesConstants.APOLLO_BOOTSTRAP_PROPERTY_SOURCE_NAME)) { // ensure ApolloBootstrapPropertySources is still the first ensureBootstrapPropertyPrecedence(environment); environment.getPropertySources() .addAfter(PropertySourcesConstants.APOLLO_BOOTSTRAP_PROPERTY_SOURCE_NAME, composite); } else { environment.getPropertySources().addFirst(composite); } } private void ensureBootstrapPropertyPrecedence(ConfigurableEnvironment environment) { MutablePropertySources propertySources = environment.getPropertySources(); PropertySource bootstrapPropertySource = propertySources .get(PropertySourcesConstants.APOLLO_BOOTSTRAP_PROPERTY_SOURCE_NAME); // not exists or already in the first place if (bootstrapPropertySource == null || propertySources.precedenceOf(bootstrapPropertySource) == 0) { return; } propertySources.remove(PropertySourcesConstants.APOLLO_BOOTSTRAP_PROPERTY_SOURCE_NAME); propertySources.addFirst(bootstrapPropertySource); } private void initializeAutoUpdatePropertiesFeature(ConfigurableListableBeanFactory beanFactory) { if (!configUtil.isAutoUpdateInjectedSpringPropertiesEnabled() || !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; } // for test only static void reset() { NAMESPACE_NAMES.clear(); AUTO_UPDATE_INITIALIZED_BEAN_FACTORIES.clear(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy