java - 如何在java代码中的资源上调用Spring的当前属性占位符?

Posted

技术标签:

【中文标题】java - 如何在java代码中的资源上调用Spring的当前属性占位符?【英文标题】:How to invoke Spring's current property placeholder on resource in java code? 【发布时间】:2013-01-24 04:45:50 【问题描述】:

Spring 占位符机制非常干净和健壮,不幸的是它只适用于 Spring 文件。

我正在使用 EhCahe,我想在 ehcache.xml 文件上使用占位符机制。我有自己的 EhCache 工厂 bean,我可以将此库配置作为 InputStream 提供。所以我需要做的就是实现我的目标:

从类路径读取 xml 文件内容 访问属性占位符当前 spring.xml 文件(我的 bean 已配置) 在读取资源上调用占位符 将资源作为 InputStream 还给库

所以我的问题是,如何做到这一点,就像 Spring 允许的那样紧凑?我想避免自己创建占位符,所以代码会尽可能少地“魔法”,所以我想使用 xml 文件中的属性配置。

【问题讨论】:

【参考方案1】:

EhCache 支持 ehcache.xml 文件中的系统属性占位符替换,因此一种选择是将 Spring 占位符值复制到系统属性中,以便在 ehcache.xml 文件中引用它们:

在spring上下文xml中...

<!-- Copy Spring placeholder value to System props -->
<bean id="systemProps" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetObject" value="#@systemProperties" />
    <property name="targetMethod" value="putAll" />
    <property name="arguments">
        <util:properties>
            <prop key="cache.ttl">$cache.ttl</prop>
        </util:properties>
    </property>
</bean>

然后在您的 ehcache.xml 文件中,您现在可以使用上面填充的 $cache.ttl 占位符:

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
            xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
    <cache name="myCache" timeToLiveSeconds="$cache.ttl" maxElementsInMemory="1000" overflowToDisk="false" />
</ehcache>

【讨论】:

见:vinaycn.wordpress.com/2014/09/02/…【参考方案2】:

Ehcache 有一个以编程方式定义新缓存的 api。为什么你不能做一个与春天一起启动并自动填充的豆子?这样你就不必创建一个自动的 EhCache.xml,但是你可以在一个 spring 上下文文件中定义你想要的所有缓存。

【讨论】:

你的意思是把ehcache.xml改写成spring.xml bean格式?它仍然是一种选择,但是对于习惯使用 ehcache.xml 格式的人来说,这是一个令人震惊的选择,迫使他们学习“新”格式。【参考方案3】:

不必使用系统属性。但是,您必须在构建期间解析占位符。

像这样把你的属性放到对象中:

<bean id="cacheProperties" class="java.util.Properties">
    <constructor-arg>
        <props>
            <prop key="prop1">#prop1</prop>
            <prop key="prop2">#prop2</prop>
        </props>
    </constructor-arg>
</bean>

并将它们设置为您的自定义 PlaceHolderHelper:

    <bean id="cachePlaceholderHelper"
      class="com.PlaceholderHelper" depends-on="cacheProperties">
    <property name="configFileResource" value="classpath:cacheConfig.xml"/>
    <property name="properties" ref="cacheProperties"/>
</bean>

PlaceholderHelper 可能看起来像这样:

private Resource configFileResource;
private Properties properties;
private Resource resolvedConfigResource;

@PostConstruct
public void replace() throws IOException 
    PropertyPlaceholderHelper helper = new PropertyPlaceholderHelper("$", "");

    if (this.properties != null && this.configFileResource != null) 
        File file = this.configFileResource.getFile();
        String content = FileUtils.readFileToString(file);
        String result = helper.replacePlaceholders(content, this.properties);
        File resolvedCacheConfigFile = new File("resolvedCacheConfig");
        FileUtils.write(resolvedCacheConfigFile, result);

        resolvedConfigResource = new FileSystemResource(resolvedCacheConfigFile);
        logger.info(String.format("Placeholders in file %s were replaced.", file.getName()));
    

p:configLocation 更改为已解析的资源:

p:configLocation="#cachePlaceholderHelper.resolvedConfigResource

现在您可以在 XML 的任何地方使用 $prop1 表达式。

【讨论】:

以上是关于java - 如何在java代码中的资源上调用Spring的当前属性占位符?的主要内容,如果未能解决你的问题,请参考以下文章

java项目和web项目中的过滤器文件怎么使用?

如何使用java代码在sp值中分配文本大小

如何在android的代码中调用某个组件属性

如何从 Java 中的 oracle SP 返回 sys_refcursor?

java编译器的代码优化问题

db2中的SP是不是等待触发器执行