本文共 9544 字,大约阅读时间需要 31 分钟。
在spring中很重要的接口,spring以来的各种环境都是它的实现:
属性解析接口,主要有一下核心方法:boolean containsProperty(String key); //是否包含指定的key String getProperty(String key);//通过key查找属性,不存在返回null String getProperty(String key, String defaultValue);//通过key查找属性,不存在返回默认值T getProperty(String key, Class targetType);//通过key查找属性,类型转换 T getProperty(String key, Class targetType, T defaultValue);//通过key查找属性,类型转换,不存在返回默认值 String getRequiredProperty(String key) throws IllegalStateException;//获取必须属性值,不存在抛出异常 T getRequiredProperty(String key, Class targetType) throws IllegalStateException;//获取必须属性,类型转换,不存在抛出异常 String resolvePlaceholders(String text);//解析${...}文本,并返回解析值 String resolveRequiredPlaceholders(String text) throws IllegalArgumentException;//解析${...}文本,不存在抛出异常
interface Environment extends PropertyResolver:环境实现核心方法:
String[] getActiveProfiles();//获取激活的环境可以通过spring.profiles.active设置String[] getDefaultProfiles();//默认激活环境组boolean acceptsProfiles(String... profiles);//判断一个或多个profile包含在当前激活组中,如果profile是!开头,则判断不在boolean acceptsProfiles(Profiles profiles);//判断当前激活环境是否是profiles
interface ConfigurablePropertyResolver extends PropertyResolver,可配置解析器:
//获取转换服务 ConfigurableConversionService getConversionService(); //设置类型转换服务 void setConversionService(ConfigurableConversionService conversionService); //placehold前缀 void setPlaceholderPrefix(String placeholderPrefix); //placehold后缀 void setPlaceholderSuffix(String placeholderSuffix); //设置分隔符 void setValueSeparator(@Nullable String valueSeparator); //设置忽略不可解析 void setIgnoreUnresolvableNestedPlaceholders(boolean ignoreUnresolvableNestedPlaceholders); //设置必须属性 void setRequiredProperties(String... requiredProperties); //验证必须属性 void validateRequiredProperties() throws MissingRequiredPropertiesException;
interface ConfigurableEnvironment extends Environment, ConfigurablePropertyResolver:
可配置环境://设置激活的profiles void setActiveProfiles(String... profiles); //添加激活profile void addActiveProfile(String profile); //设置默认profile void setDefaultProfiles(String... profiles); //可变属性资源表 MutablePropertySources getPropertySources(); //获取系统属性 MapgetSystemProperties(); //获取系统环境 Map getSystemEnvironment(); //合并环境,子父环境合并 void merge(ConfigurableEnvironment parent);
abstract class AbstractEnvironment implements ConfigurableEnvironment
第一个环境抽象实现,让我看看里边的重要结构://激活的profile集合private final SetactiveProfiles = new LinkedHashSet<>();//默认的profile集合private final Set defaultProfiles = new LinkedHashSet<>(getReservedDefaultProfiles());//属性资源集合private final MutablePropertySources propertySources = new MutablePropertySources();//资源解析器private final ConfigurablePropertyResolver propertyResolver =new PropertySourcesPropertyResolver(this.propertySources);//重要的方法,直接上原文/** * Customize the set of {@link PropertySource} objects to be searched by this * {@code Environment} during calls to {@link #getProperty(String)} and related * methods. * * Subclasses that override this method are encouraged to add property * sources using {@link MutablePropertySources#addLast(PropertySource)} such that * further subclasses may call {@code super.customizePropertySources()} with * predictable results. For example: *
* public class Level1Environment extends AbstractEnvironment { * @Override * protected void customizePropertySources(MutablePropertySources propertySources) { * super.customizePropertySources(propertySources); // no-op from base class * propertySources.addLast(new PropertySourceA(...)); * propertySources.addLast(new PropertySourceB(...)); * } * } * * public class Level2Environment extends Level1Environment { * @Override * protected void customizePropertySources(MutablePropertySources propertySources) { * super.customizePropertySources(propertySources); // add all from superclass * propertySources.addLast(new PropertySourceC(...)); * propertySources.addLast(new PropertySourceD(...)); * } * } ** In this arrangement, properties will be resolved against sources A, B, C, D in that * order. That is to say that property source "A" has precedence over property source * "D". If the {@code Level2Environment} subclass wished to give property sources C * and D higher precedence than A and B, it could simply call * {@code super.customizePropertySources} after, rather than before adding its own: ** public class Level2Environment extends Level1Environment { * @Override * protected void customizePropertySources(MutablePropertySources propertySources) { * propertySources.addLast(new PropertySourceC(...)); * propertySources.addLast(new PropertySourceD(...)); * super.customizePropertySources(propertySources); // add all from superclass * } * } ** The search order is now C, D, A, B as desired. * *Beyond these recommendations, subclasses may use any of the {@code add*}, * {@code remove}, or {@code replace} methods exposed by {@link MutablePropertySources} * in order to create the exact arrangement of property sources desired. * *
The base implementation registers no property sources. * *
Note that clients of any {@link ConfigurableEnvironment} may further customize * property sources via the {@link #getPropertySources()} accessor, typically within * an {@link org.springframework.context.ApplicationContextInitializer * ApplicationContextInitializer}. For example: *
* ConfigurableEnvironment env = new StandardEnvironment(); * env.getPropertySources().addLast(new PropertySourceX(...)); ** *A warning about instance variable access
* Instance variables declared in subclasses and having default initial values should * not be accessed from within this method. Due to Java object creation * lifecycle constraints, any initial value will not yet be assigned when this * callback is invoked by the {@link #AbstractEnvironment()} constructor, which may * lead to a {@code NullPointerException} or other problems. If you need to access * default values of instance variables, leave this method as a no-op and perform * property source manipulation and instance variable access directly within the * subclass constructor. Note that assigning values to instance variables is * not problematic; it is only attempting to read default values that must be avoided. * * @see MutablePropertySources * @see PropertySourcesPropertyResolver * @see org.springframework.context.ApplicationContextInitializer */ protected void customizePropertySources(MutablePropertySources propertySources) { }
class StandardEnvironment extends AbstractEnvironment:标准环境,
public static final String SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME = "systemEnvironment"; public static final String SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME = "systemProperties"; //标准环境在构造时,添加了系统环境资源和系统属性资源 protected void customizePropertySources(MutablePropertySources propertySources) { propertySources.addLast( new PropertiesPropertySource(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, getSystemProperties())); propertySources.addLast( new SystemEnvironmentPropertySource(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, getSystemEnvironment())); }
class StandardServletEnvironment extends StandardEnvironment implements ConfigurableWebEnvironment:标准的web环境:
/** Servlet context init parameters property source name: {@value}. */ public static final String SERVLET_CONTEXT_PROPERTY_SOURCE_NAME = "servletContextInitParams"; /** Servlet config init parameters property source name: {@value}. */ public static final String SERVLET_CONFIG_PROPERTY_SOURCE_NAME = "servletConfigInitParams"; /** JNDI property source name: {@value}. */ public static final String JNDI_PROPERTY_SOURCE_NAME = "jndiProperties"; //增加了serveltCOntext资源,serveltConfig资源,可选的jndi属性资源,比标准环境具有更高的优先级,使用了StubPropertySource类型进行占位 protected void customizePropertySources(MutablePropertySources propertySources) { propertySources.addLast(new StubPropertySource(SERVLET_CONFIG_PROPERTY_SOURCE_NAME)); propertySources.addLast(new StubPropertySource(SERVLET_CONTEXT_PROPERTY_SOURCE_NAME)); if (JndiLocatorDelegate.isDefaultJndiEnvironmentAvailable()) { propertySources.addLast(new JndiPropertySource(JNDI_PROPERTY_SOURCE_NAME)); } super.customizePropertySources(propertySources); }//实际的资源生成后,通过资源的replace方法替换StubPropertySource @Override public void initPropertySources(@Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig) { WebApplicationContextUtils.initServletPropertySources(getPropertySources(), servletContext, servletConfig); }
spring系统的环境部分已经完成了.一个系统环境由这几部分构成:
1.属性资源 2.属性资源管理 3.资源类型转换器自定义转换服务:
通过void setConversionService(ConfigurableConversionService conversionService);设置自己的资源类型转换程序 增加转换器可以这样: ConfigurableConversionService getConversionService();//获取到转货服务 ConfigurableConversionService .addConverter(Converter<?, ?> converter);//添加自定义的转换服务 增加属性资源: MutablePropertySources getPropertySources(); 先获取到资源列表,然后增加资源 替换资源: 也是先获取MutablePropertySources 对象,然后使用replace替换原有的属性资源如: MutablePropertySources propertySources = environment.getPropertySources(); MockPropertySource mockEnvVars = new MockPropertySource().withProperty(“xyz”, “myValue”); propertySources.replace(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, mockEnvVars); 删除资源: MutablePropertySources propertySources = environment.getPropertySources(); propertySources.remove(StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME)转载地址:http://gbuti.baihongyu.com/