- 浏览: 92341 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
dylan0514sina.cn:
youjianbo_han_87 写道dylan0514sin ...
方法缓存 -
youjianbo_han_87:
dylan0514sina.cn 写道youjianbo_ha ...
方法缓存 -
dylan0514sina.cn:
youjianbo_han_87 写道缓存方法有意义吗,方法+ ...
方法缓存 -
youjianbo_han_87:
缓存方法有意义吗,方法+调用从缓存中取内容的方法 换成 方法+ ...
方法缓存 -
dylan0514sina.cn:
Shen.Yiyang 写道剔除策略只有方法执行的时候指定ke ...
方法缓存
PropertyResolver 是 Environment的顶层接口,主要提供属性检索和解析带占位符的文本。bean.xml配置中的所有占位符例如${}都由它解析。通过例子代码了解它的功能和使用
getProperty返回变量在Environment中对应的值
对带有${}占位符的文本解析算法如下
public class PropertySourcesPropertyResolverTests { private Properties testProperties; private MutablePropertySources propertySources; private ConfigurablePropertyResolver propertyResolver; @Before public void setUp() { propertySources = new MutablePropertySources(); propertyResolver = new PropertySourcesPropertyResolver(propertySources); testProperties = new Properties(); propertySources.addFirst(new PropertiesPropertySource("testProperties", testProperties)); } @Test public void containsProperty() { assertThat(propertyResolver.containsProperty("foo"), is(false)); testProperties.put("foo", "bar"); assertThat(propertyResolver.containsProperty("foo"), is(true)); } @Test public void getProperty() { assertThat(propertyResolver.getProperty("foo"), nullValue()); testProperties.put("foo", "bar"); assertThat(propertyResolver.getProperty("foo"), is("bar")); } @Test public void getProperty_withDefaultValue() { assertThat(propertyResolver.getProperty("foo", "myDefault"), is("myDefault")); testProperties.put("foo", "bar"); assertThat(propertyResolver.getProperty("foo"), is("bar")); } @Test public void getProperty_propertySourceSearchOrderIsFIFO() { MutablePropertySources sources = new MutablePropertySources(); PropertyResolver resolver = new PropertySourcesPropertyResolver(sources); sources.addFirst(new MockPropertySource("ps1").withProperty("pName", "ps1Value")); assertThat(resolver.getProperty("pName"), equalTo("ps1Value")); sources.addFirst(new MockPropertySource("ps2").withProperty("pName", "ps2Value")); assertThat(resolver.getProperty("pName"), equalTo("ps2Value")); sources.addFirst(new MockPropertySource("ps3").withProperty("pName", "ps3Value")); assertThat(resolver.getProperty("pName"), equalTo("ps3Value")); } @Test public void getProperty_withExplicitNullValue() { // java.util.Properties does not allow null values (because Hashtable does not) Map<String, Object> nullableProperties = new HashMap<String, Object>(); propertySources.addLast(new MapPropertySource("nullableProperties", nullableProperties)); nullableProperties.put("foo", null); assertThat(propertyResolver.getProperty("foo"), nullValue()); } @Test public void getProperty_withTargetType_andDefaultValue() { assertThat(propertyResolver.getProperty("foo", Integer.class, 42), equalTo(42)); testProperties.put("foo", 13); assertThat(propertyResolver.getProperty("foo", Integer.class, 42), equalTo(13)); } @Test public void getProperty_withStringArrayConversion() { testProperties.put("foo", "bar,baz"); assertThat(propertyResolver.getProperty("foo", String[].class), equalTo(new String[] { "bar", "baz" })); } @Test public void getProperty_withNonConvertibleTargetType() { testProperties.put("foo", "bar"); class TestType { } try { propertyResolver.getProperty("foo", TestType.class); fail("Expected IllegalArgumentException due to non-convertible types"); } catch (IllegalArgumentException ex) { // expected } } @Test public void getProperty_doesNotCache_replaceExistingKeyPostConstruction() { String key = "foo"; String value1 = "bar"; String value2 = "biz"; HashMap<String, Object> map = new HashMap<String, Object>(); map.put(key, value1); // before construction MutablePropertySources propertySources = new MutablePropertySources(); propertySources.addFirst(new MapPropertySource("testProperties", map)); PropertyResolver propertyResolver = new PropertySourcesPropertyResolver(propertySources); assertThat(propertyResolver.getProperty(key), equalTo(value1)); map.put(key, value2); // after construction and first resolution assertThat(propertyResolver.getProperty(key), equalTo(value2)); } @Test public void getProperty_doesNotCache_addNewKeyPostConstruction() { HashMap<String, Object> map = new HashMap<String, Object>(); MutablePropertySources propertySources = new MutablePropertySources(); propertySources.addFirst(new MapPropertySource("testProperties", map)); PropertyResolver propertyResolver = new PropertySourcesPropertyResolver(propertySources); assertThat(propertyResolver.getProperty("foo"), equalTo(null)); map.put("foo", "42"); assertThat(propertyResolver.getProperty("foo"), equalTo("42")); } @Test public void getPropertySources_replacePropertySource() { propertySources = new MutablePropertySources(); propertyResolver = new PropertySourcesPropertyResolver(propertySources); propertySources.addLast(new MockPropertySource("local").withProperty("foo", "localValue")); propertySources.addLast(new MockPropertySource("system").withProperty("foo", "systemValue")); // 'local' was added first so has precedence assertThat(propertyResolver.getProperty("foo"), equalTo("localValue")); // replace 'local' with new property source propertySources.replace("local", new MockPropertySource("new").withProperty("foo", "newValue")); // 'system' now has precedence assertThat(propertyResolver.getProperty("foo"), equalTo("newValue")); assertThat(propertySources.size(), is(2)); } @Test public void getRequiredProperty() { testProperties.put("exists", "xyz"); assertThat(propertyResolver.getRequiredProperty("exists"), is("xyz")); try { propertyResolver.getRequiredProperty("bogus"); fail("expected IllegalStateException"); } catch (IllegalStateException ex) { // expected } } @Test public void getRequiredProperty_withStringArrayConversion() { testProperties.put("exists", "abc,123"); assertThat(propertyResolver.getRequiredProperty("exists", String[].class), equalTo(new String[] { "abc", "123" })); try { propertyResolver.getRequiredProperty("bogus", String[].class); fail("expected IllegalStateException"); } catch (IllegalStateException ex) { // expected } } @Test public void resolvePlaceholders() { MutablePropertySources propertySources = new MutablePropertySources(); propertySources.addFirst(new MockPropertySource().withProperty("key", "value")); PropertyResolver resolver = new PropertySourcesPropertyResolver(propertySources); assertThat(resolver.resolvePlaceholders("Replace this ${key}"), equalTo("Replace this value")); } @Test public void resolvePlaceholders_withUnresolvable() { MutablePropertySources propertySources = new MutablePropertySources(); propertySources.addFirst(new MockPropertySource().withProperty("key", "value")); PropertyResolver resolver = new PropertySourcesPropertyResolver(propertySources); assertThat(resolver.resolvePlaceholders("Replace this ${key} plus ${unknown}"), equalTo("Replace this value plus ${unknown}")); } @Test public void resolvePlaceholders_withDefaultValue() { MutablePropertySources propertySources = new MutablePropertySources(); propertySources.addFirst(new MockPropertySource().withProperty("key", "value")); PropertyResolver resolver = new PropertySourcesPropertyResolver(propertySources); assertThat(resolver.resolvePlaceholders("Replace this ${key} plus ${unknown:defaultValue}"), equalTo("Replace this value plus defaultValue")); } @Test(expected=IllegalArgumentException.class) public void resolvePlaceholders_withNullInput() { new PropertySourcesPropertyResolver(new MutablePropertySources()).resolvePlaceholders(null); } @Test public void resolveRequiredPlaceholders() { MutablePropertySources propertySources = new MutablePropertySources(); propertySources.addFirst(new MockPropertySource().withProperty("key", "value")); PropertyResolver resolver = new PropertySourcesPropertyResolver(propertySources); assertThat(resolver.resolveRequiredPlaceholders("Replace this ${key}"), equalTo("Replace this value")); } @Test(expected=IllegalArgumentException.class) public void resolveRequiredPlaceholders_withUnresolvable() { MutablePropertySources propertySources = new MutablePropertySources(); propertySources.addFirst(new MockPropertySource().withProperty("key", "value")); PropertyResolver resolver = new PropertySourcesPropertyResolver(propertySources); resolver.resolveRequiredPlaceholders("Replace this ${key} plus ${unknown}"); } @Test public void resolveRequiredPlaceholders_withDefaultValue() { MutablePropertySources propertySources = new MutablePropertySources(); propertySources.addFirst(new MockPropertySource().withProperty("key", "value")); PropertyResolver resolver = new PropertySourcesPropertyResolver(propertySources); assertThat(resolver.resolveRequiredPlaceholders("Replace this ${key} plus ${unknown:defaultValue}"), equalTo("Replace this value plus defaultValue")); } @Test(expected=IllegalArgumentException.class) public void resolveRequiredPlaceholders_withNullInput() { new PropertySourcesPropertyResolver(new MutablePropertySources()).resolveRequiredPlaceholders(null); } @Test public void getPropertyAsClass() throws ClassNotFoundException, LinkageError { MutablePropertySources propertySources = new MutablePropertySources(); propertySources.addFirst(new MockPropertySource().withProperty("some.class", SpecificType.class.getName())); PropertyResolver resolver = new PropertySourcesPropertyResolver(propertySources); assertTrue(resolver.getPropertyAsClass("some.class", SomeType.class).equals(SpecificType.class)); } @Test public void getPropertyAsClass_withInterfaceAsTarget() throws ClassNotFoundException, LinkageError { MutablePropertySources propertySources = new MutablePropertySources(); propertySources.addFirst(new MockPropertySource().withProperty("some.class", SomeType.class.getName())); PropertyResolver resolver = new PropertySourcesPropertyResolver(propertySources); assertTrue(resolver.getPropertyAsClass("some.class", SomeType.class).equals(SomeType.class)); } @Test(expected=ConversionException.class) public void getPropertyAsClass_withMismatchedTypeForValue() { MutablePropertySources propertySources = new MutablePropertySources(); propertySources.addFirst(new MockPropertySource().withProperty("some.class", "java.lang.String")); PropertyResolver resolver = new PropertySourcesPropertyResolver(propertySources); resolver.getPropertyAsClass("some.class", SomeType.class); } @Test(expected=ConversionException.class) public void getPropertyAsClass_withNonExistentClassForValue() { MutablePropertySources propertySources = new MutablePropertySources(); propertySources.addFirst(new MockPropertySource().withProperty("some.class", "some.bogus.Class")); PropertyResolver resolver = new PropertySourcesPropertyResolver(propertySources); resolver.getPropertyAsClass("some.class", SomeType.class); } @Test public void getPropertyAsClass_withObjectForValue() { MutablePropertySources propertySources = new MutablePropertySources(); propertySources.addFirst(new MockPropertySource().withProperty("some.class", new SpecificType())); PropertyResolver resolver = new PropertySourcesPropertyResolver(propertySources); assertTrue(resolver.getPropertyAsClass("some.class", SomeType.class).equals(SpecificType.class)); } @Test(expected=ConversionException.class) public void getPropertyAsClass_withMismatchedObjectForValue() { MutablePropertySources propertySources = new MutablePropertySources(); propertySources.addFirst(new MockPropertySource().withProperty("some.class", new Integer(42))); PropertyResolver resolver = new PropertySourcesPropertyResolver(propertySources); resolver.getPropertyAsClass("some.class", SomeType.class); } @Test public void getPropertyAsClass_withRealClassForValue() { MutablePropertySources propertySources = new MutablePropertySources(); propertySources.addFirst(new MockPropertySource().withProperty("some.class", SpecificType.class)); PropertyResolver resolver = new PropertySourcesPropertyResolver(propertySources); assertTrue(resolver.getPropertyAsClass("some.class", SomeType.class).equals(SpecificType.class)); } @Test(expected=ConversionException.class) public void getPropertyAsClass_withMismatchedRealClassForValue() { MutablePropertySources propertySources = new MutablePropertySources(); propertySources.addFirst(new MockPropertySource().withProperty("some.class", Integer.class)); PropertyResolver resolver = new PropertySourcesPropertyResolver(propertySources); resolver.getPropertyAsClass("some.class", SomeType.class); } @Test public void setRequiredProperties_andValidateRequiredProperties() { // no properties have been marked as required -> validation should pass propertyResolver.validateRequiredProperties(); // mark which properties are required propertyResolver.setRequiredProperties("foo", "bar"); // neither foo nor bar properties are present -> validating should throw try { propertyResolver.validateRequiredProperties(); fail("expected validation exception"); } catch (MissingRequiredPropertiesException ex) { assertThat(ex.getMessage(), equalTo( "The following properties were declared as required " + "but could not be resolved: [foo, bar]")); } // add foo property -> validation should fail only on missing 'bar' property testProperties.put("foo", "fooValue"); try { propertyResolver.validateRequiredProperties(); fail("expected validation exception"); } catch (MissingRequiredPropertiesException ex) { assertThat(ex.getMessage(), equalTo( "The following properties were declared as required " + "but could not be resolved: [bar]")); } // add bar property -> validation should pass, even with an empty string value testProperties.put("bar", ""); propertyResolver.validateRequiredProperties(); } @Test public void resolveNestedPropertyPlaceholders() { MutablePropertySources ps = new MutablePropertySources(); ps.addFirst(new MockPropertySource() .withProperty("p1", "v1") .withProperty("p2", "v2") .withProperty("p3", "${p1}:${p2}") // nested placeholders .withProperty("p4", "${p3}") // deeply nested placeholders .withProperty("p5", "${p1}:${p2}:${bogus}") // unresolvable placeholder .withProperty("p6", "${p1}:${p2}:${bogus:def}") // unresolvable w/ default .withProperty("pL", "${pR}") // cyclic reference left .withProperty("pR", "${pL}") // cyclic reference right ); ConfigurablePropertyResolver pr = new PropertySourcesPropertyResolver(ps); assertThat(pr.getProperty("p1"), equalTo("v1")); assertThat(pr.getProperty("p2"), equalTo("v2")); assertThat(pr.getProperty("p3"), equalTo("v1:v2")); assertThat(pr.getProperty("p4"), equalTo("v1:v2")); try { pr.getProperty("p5"); } catch (IllegalArgumentException ex) { assertThat(ex.getMessage(), containsString( "Could not resolve placeholder 'bogus' in string value \"${p1}:${p2}:${bogus}\"")); } assertThat(pr.getProperty("p6"), equalTo("v1:v2:def")); try { pr.getProperty("pL"); } catch (StackOverflowError ex) { // no explicit handling for cyclic references for now } } @Test public void ignoreUnresolvableNestedPlaceholdersIsConfigurable() { MutablePropertySources ps = new MutablePropertySources(); ps.addFirst(new MockPropertySource() .withProperty("p1", "v1") .withProperty("p2", "v2") .withProperty("p3", "${p1}:${p2}:${bogus:def}") // unresolvable w/ default .withProperty("p4", "${p1}:${p2}:${bogus}") // unresolvable placeholder ); ConfigurablePropertyResolver pr = new PropertySourcesPropertyResolver(ps); assertThat(pr.getProperty("p1"), equalTo("v1")); assertThat(pr.getProperty("p2"), equalTo("v2")); assertThat(pr.getProperty("p3"), equalTo("v1:v2:def")); // placeholders nested within the value of "p4" are unresolvable and cause an // exception by default try { pr.getProperty("p4"); } catch (IllegalArgumentException ex) { assertThat(ex.getMessage(), containsString( "Could not resolve placeholder 'bogus' in string value \"${p1}:${p2}:${bogus}\"")); } // relax the treatment of unresolvable nested placeholders pr.setIgnoreUnresolvableNestedPlaceholders(true); // and observe they now pass through unresolved assertThat(pr.getProperty("p4"), equalTo("v1:v2:${bogus}")); // resolve[Nested]Placeholders methods behave as usual regardless the value of // ignoreUnresolvableNestedPlaceholders assertThat(pr.resolvePlaceholders("${p1}:${p2}:${bogus}"), equalTo("v1:v2:${bogus}")); try { pr.resolveRequiredPlaceholders("${p1}:${p2}:${bogus}"); } catch (IllegalArgumentException ex) { assertThat(ex.getMessage(), containsString( "Could not resolve placeholder 'bogus' in string value \"${p1}:${p2}:${bogus}\"")); } } interface SomeType { } static class SpecificType implements SomeType { } }
getProperty返回变量在Environment中对应的值
对带有${}占位符的文本解析算法如下
protected String parseStringValue( String strVal, PlaceholderResolver placeholderResolver, Set<String> visitedPlaceholders) { StringBuilder buf = new StringBuilder(strVal); int startIndex = strVal.indexOf(this.placeholderPrefix); while (startIndex != -1) { int endIndex = findPlaceholderEndIndex(buf, startIndex); if (endIndex != -1) { String placeholder = buf.substring(startIndex + this.placeholderPrefix.length(), endIndex); String originalPlaceholder = placeholder; if (!visitedPlaceholders.add(originalPlaceholder)) { throw new IllegalArgumentException( "Circular placeholder reference '" + originalPlaceholder + "' in property definitions"); } // Recursive invocation, parsing placeholders contained in the placeholder key. placeholder = parseStringValue(placeholder, placeholderResolver, visitedPlaceholders); // Now obtain the value for the fully resolved key... String propVal = placeholderResolver.resolvePlaceholder(placeholder); if (propVal == null && this.valueSeparator != null) { int separatorIndex = placeholder.indexOf(this.valueSeparator); if (separatorIndex != -1) { String actualPlaceholder = placeholder.substring(0, separatorIndex); String defaultValue = placeholder.substring(separatorIndex + this.valueSeparator.length()); propVal = placeholderResolver.resolvePlaceholder(actualPlaceholder); if (propVal == null) { propVal = defaultValue; } } } if (propVal != null) { // Recursive invocation, parsing placeholders contained in the // previously resolved placeholder value. propVal = parseStringValue(propVal, placeholderResolver, visitedPlaceholders); buf.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal); if (logger.isTraceEnabled()) { logger.trace("Resolved placeholder '" + placeholder + "'"); } startIndex = buf.indexOf(this.placeholderPrefix, startIndex + propVal.length()); } else if (this.ignoreUnresolvablePlaceholders) { // Proceed with unprocessed value. startIndex = buf.indexOf(this.placeholderPrefix, endIndex + this.placeholderSuffix.length()); } else { throw new IllegalArgumentException("Could not resolve placeholder '" + placeholder + "'" + " in string value \"" + strVal + "\""); } visitedPlaceholders.remove(originalPlaceholder); } else { startIndex = -1; } } return buf.toString();
发表评论
-
支持不同运行环境下的属性处理--Environment 特性
2013-07-14 01:47 4087介绍 Environment架构是spring 3.1版本引 ... -
支持开发、测试、生产环境下bean配置切换的profiles特性
2013-07-11 12:31 5541介绍 Bean definition profiles ... -
方法缓存
2013-07-10 18:20 4192介绍 spring3.1之后提供了方法的缓存支持,透明的将 ... -
基于xml schema的扩展标签
2013-07-09 13:34 1542xml schema是spring 2.0版本之后引入的,在之 ... -
BeanDefinition数据流
2013-07-08 19:41 1807BeanDefinition是Spring配置文件中bean定 ... -
bean的创建周期回调
2013-06-29 16:24 1527初始化回调 实现org.springframework ... -
Scope实现原理
2013-06-27 18:02 3316内置Scope分类 Singleton 每个IOC容器对一个b ... -
MethodInjection 动态方法替换原理
2013-06-21 14:45 1398singleton实例依赖于prototy ... -
AbstractBeanFactory获取bean周期
2013-05-11 22:58 897AbstractBeanFactory是IOC容器实现的骨 ...
相关推荐
在用freemaker模板的时候,第一步都会将word转换为xml格式文件,解析成xml文件经常会出现(个别、很多)字段占位符、变量值被分离,被分离的字段少的还好能手动改改,字段多了能让你直接发疯,此代码脚本轻松解决...
动态生成SQL语句,通过给定的条件自动填充预设SQL语句的配位符,而避免通过程序判断生成SQL语句
wps演示教程:文本占位符的特点与使用.docx
今天小编就为大家分享一篇关于java字符串中${}或者{}等的占位符替换工具类,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
JVFloat.js, jquery/zepto插件模拟 Matt D Smith占位符文本浮动 #JVFloat.js 演示插件 jQuery和Zepto插件来模拟 JVFloatLabeledTextField的行为,这基于从Matt的概念。 史密斯 。在博客上阅读更多关于的文章。请注意...
设置textfield占位符的颜色大小,开始编辑的时候可以让占位符跟着移动..
工程运行环境有研发,测试和生产,不同的运行环境配置不同,使用maven 占位符,不同环境使用不同的配置
属性占位符配置器
Day Player是一款Sketch的图片占位符插入插件,对于设计师来说这款插件可以帮助节省很多时间,它可以在任意Sketch文档中插入一个可定制的图片占位符,其中内置多种可选占位符服务。当你激活控件的时候,还可以设定...
主要介绍了基于SPRINGBOOT配置文件占位符过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
EPLAN P8 占位符的创建和运用,选择电气图中的相关电路,点击“插入” --------“占位符对象”,在占位符对象属性画面, 填写名称,并在分配画面-------属性-----技术参数后面的变量处填写变量名称。
Java三种处理字符转占位符及其时间性能的对比
在React Native渲染文本或媒体内容之前,显示一些占位符的内容
带有占位符的TextView,可修改占位符颜色等属性,简单易用
20.7版本,java处理word 的jar包,修改版本,无页眉页脚水印,无文档长度限制,已亲测有效,使用方法:https://blog.csdn.net/qq_21134557/article/details/107845002 2022-11-07 针对评论区问题,重新更新一下,并...
java 替换word 占位符
React Native的占位符(Placeholder)
打字动画文本占位符特效jQuery插件
Bacon Ipsum 是一个内置聚合物的小组件,旨在帮助您在开发工作流程中管理模板中的占位符文本。 安装组件后,您可以访问生成占位符文本的自定义标签。 使用这种方法有一些好处: 使用一个标签生成您需要的任何占位符...