2009-10-07 3 views
7

У меня есть контекст весной XML-файл с этимSpring контекст конфигурации Свойство placholder ehcahe

<context:property-placeholder location="classpath:cacheConfig.properties"/> 

<bean id="cacheManager" 
    class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"> 
    <property name="cacheManagerName" value="cacheName"/> 
    <property name="shared" value="false"/> 
    <property name="configLocation" value="classpath:cacheConfig.xml"/> 
</bean> 

целью является, чтобы позволить клиенту редактировать файл свойств, как этот

cache.maxMemoryElements="2000" 

, а затем в фактическом файле cacheConfig.xml есть это

<cache name="someCacheName" 
    maxElementsInMemory="${cache.maxMemoryElements}" ... /> 

, так что элементы, которые мы не хотим, чтобы клиент ch ange не подвергаются. Конечно, приведенные выше детали только частично детализированы и НЕ работают. В настоящее время я вижу это в файле журнала

Invocation of init method failed; nested exception is net.sf.ehcache.CacheException: Error configuring from input stream. Initial cause was null:149: Could not set attribute "maxElementsInMemory". 

Заранее спасибо ...

ответ

12

В вашем примере используется EhCacheManagerFactoryBean, чтобы предоставить ссылку на CacheManager, с тайниками, определенными во внешнем файле cacheConfig.xml. Как отмечал @ ChssPly76, свойство Spring's resolver работает только в собственных файлах определения Spring.

Однако, вы не должны определить отдельные кэши во внешнем файле, вы можете определить их прямо в файле определения Spring бина, используя EhCacheFactoryBean:

FactoryBean, который создает именованный Ehcache Cache экземпляр ... Если указанных именованный кэш не настроен в дескрипторе конфигурации кэша , этот FactoryBean будет построить экземпляр Cache с прилагаемым именем и указанных свойства кэшем и добавьте его в CacheManager для последующего поиска.

Другими словами, если вы используете EhCacheFactoryBean для обозначения имени кэша, который еще не определен в cacheConfig.xml, то весна будет создать и настроить новый экземпляр кэша и зарегистрировать его с CacheManager во время выполнения.Это включает в себя задание вещи, как maxElementsInMemory, и потому, что это будет указано в файле определения Spring бина, вы получаете полную поддержку недвижимости распознаватель:

<context:property-placeholder location="classpath:cacheConfig.properties"/> 

<bean id="myCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean"> 
    <property name="cacheManager" ref="cacheManager"/> 
    <property name="maxElementsInMemory" value="${cache.maxMemoryElements}"/> 
</bean> 

<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"> 
    <property name="shared" value="false"/> 
    <property name="configLocation" value="classpath:cacheConfig.xml"/> 
</bean> 
+0

Спасибо! Это позволяет мне преодолеть горб настолько, что я могу дойти до такой степени, что мне бы хотелось. –

+3

Что делать, если вы хотите настроить что-то, что не является кешем? Например, свойство cacheManagerPeerListenerFactory? –

3

Это не то, как работает PropertyPlaceholderConfigurer. Его можно использовать для замены значений в контексте, но не в произвольных внешних файлах. И cacheConfig.xml - это внешний файл - он просто передается Spring в EH Cache.

2

Если вы используете Maven или Ant, обе имеют возможность выполнять фильтрацию токенов в файлах ресурсов.

Для Maven, вы могли бы сделать что-то вроде

<cache name="someCacheName" 
    maxElementsInMemory="${cache.maxMemoryElements}" ... /> 

И в файле фильтра, или в самом POM, имеют

cache.maxMemoryElements = 200 

Resource Filtering in Maven: The Definitive Guide

С помощью Ant вы это делаете с FilterSets и задачей <copy>.

+1

+1, но главное помните, что при замене свойств Ant и Maven происходит ** время сборки ** в отличие от заполнитель свойств Spring, где это происходит во время выполнения. – ChssPly76

+0

Да, отличная точка –

2

Для тех, кто должен изменить путь diskstore, который не может быть установлен как в ehcache javadoc указано, что параметр diskstore игнорируется, вы можете создать свою собственную реализацию EhCacheManagerFactoryBean, которая позволяет вводить путь diskstore; Вы в основном должны перехватить создание CacheManager и изменения конфигурации передается вместе с помощью свойства diskstore, например:

private String diskStorePath; 

...getter/setter 


public void afterPropertiesSet() throws IOException, CacheException { 
    if (this.shared) { 
     // Shared CacheManager singleton at the VM level. 
     if (this.configLocation != null) { 
      this.cacheManager = CacheManager.create(this.createConfig()); 
     } 
     else { 
      this.cacheManager = CacheManager.create(); 
     } 
    } 
    else { 
     // Independent CacheManager instance (the default). 
     if (this.configLocation != null) { 
      this.cacheManager = new CacheManager(this.createConfig()); 
     } 
     else { 
      this.cacheManager = new CacheManager(); 
     } 
    } 
    if (this.cacheManagerName != null) { 
     this.cacheManager.setName(this.cacheManagerName); 
    } 
} 

private Configuration createConfig() throws CacheException, IOException { 
    Configuration config = ConfigurationFactory.parseConfiguration(this.configLocation.getInputStream()); 

    DiskStoreConfiguration diskStoreConfiguration = config.getDiskStoreConfiguration(); 
    if (diskStoreConfiguration == null) { 
     DiskStoreConfiguration diskStoreConfigurationParameter = new DiskStoreConfiguration(); 
     diskStoreConfigurationParameter.setPath(getDiskStorePath()); 
     config.addDiskStore(diskStoreConfigurationParameter); 
    } else { 
     diskStoreConfiguration.setPath(getDiskStorePath()); 
    } 

    return config; 
} 

Весна конфигурации будет выглядеть следующим образом:

<bean id="cacheManager" class="com.yourcompany.package.MyEhCacheManagerFactoryBean" depends-on="placeholderConfig"> 
    <property name="diskStorePath" value="${diskstore.path}"/> 
    <property name="configLocation" value="classpath:ehcache.xml" /> 
</bean> 
+0

просто чтобы добавить к этому полезное сообщение: если вам нужно получить доступ к свойству jndi, вы можете установить его через: <свойство name = "diskStorePath" value = "$ jndi {property/ehcache/diskstore}" /> – Martin

Смежные вопросы