有时候,开发者需要在系统的bean初始化前,内置环境变量到Spring的Environment,下面就介绍三种环境变量生效方式。
介绍前,先提供下内置环境变量到Environment的公共代码。
公共代码
public class DefaultGatewayProperties {
public static final String ENDPOINT_PATH = "flux.metadata-registry.endpointPath";
public static final String ROOT_PATH = "flux.metadata-registry.root-path";
public static final String SERVICE_PATH = "flux.metadata-registry.servicePath";
public static final String ADDRESS = "flux.metadata-registry.address";
public Map<String, Object> getDefaultProperties(ConfigurableEnvironment environment) {
if (environment.getPropertySources().contains("gatewayEnvironment")) {
return null;
}
Map<String, Object> gatewayProperties = getGatewayProperties(environment);
return gatewayProperties;
}
private Map<String, Object> getGatewayProperties(ConfigurableEnvironment environment) {
Map<String, Object> gatewayEnvironment = new HashMap<>();
gatewayEnvironment.put(ENDPOINT_PATH, "/admin-endpoint");
gatewayEnvironment.put(ROOT_PATH, "/admin-endpoint");
gatewayEnvironment.put(SERVICE_PATH, "/admin-service");
String address = environment.getProperty("biz.zookeeper.address");
if (StringUtils.isBlank(address)) {
address = environment.getProperty("zookeeper.address");
}
gatewayEnvironment.put(ADDRESS, address);
// 内置配置到 Environment
MapPropertySource propertySource = new MapPropertySource("gatewayEnvironment", gatewayEnvironment);
environment.getPropertySources().addFirst(propertySource);
return gatewayEnvironment;
}
}
方式一:FactoryBean & property-placeholder
public class GatewayPropertiesFactoryBean extends DefaultGatewayProperties implements FactoryBean<Properties>, EnvironmentAware {
private Environment environment;
@Override
public Properties getObject() throws Exception {
Properties p = new Properties();
Map<String, Object> defaultProperties = super.getDefaultProperties((ConfigurableEnvironment) environment);
if (defaultProperties != null) {
p.putAll(defaultProperties);
}
return p;
}
@Override
public Class<?> getObjectType() {
return Properties.class;
}
@Override
public void setEnvironment(Environment environment) {
this.environment = environment;
}
}
<bean id="configBeanConfigBean"
class="com.access.boot.autoconfigure.env.GatewayPropertiesFactoryBean"/>
<context:property-placeholder properties-ref="configBeanConfigBean"/>
方式二:EnvironmentPostProcessor
在 META-INF/spring.factories 配置
org.springframework.boot.env.EnvironmentPostProcessor=\
com.access.boot.autoconfigure.GatewayEnvironmentPostProcessor
/**
* 通过 spring.factories 配置
* org.springframework.boot.env.EnvironmentPostProcessor=\
* com.access.boot.autoconfigure.GatewayEnvironmentPostProcessor
* 使用 @Configuration 等其他方式配置不生效
*/
public class GatewayEnvironmentPostProcessor extends DefaultGatewayProperties implements EnvironmentPostProcessor {
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
super.getDefaultProperties(environment);
}
}
方式三:GatewayApplicationContextInitializer
Apollo配置中心是通过这种方式实现Apollo的数据初始化。
在 META-INF/spring.factories 配置
org.springframework.boot.env.EnvironmentPostProcessor=\
com.access.boot.autoconfigure.GatewayApplicationContextInitializer
/**
* 通过 spring.factories 配置
* org.springframework.context.ApplicationContextInitializer=\
* com.access.boot.autoconfigure.GatewayApplicationContextInitializer
*/
public class GatewayApplicationContextInitializer extends DefaultGatewayProperties implements
ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext context) {
ConfigurableEnvironment environment = context.getEnvironment();
super.getDefaultProperties(environment);
}
}