2009-10-07 16 views
7

Ho un file XML contesto primavera con questacontesto Primavera configurazione delle proprietà-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> 

l'obiettivo è quello di consentire al cliente di modificare il file delle proprietà, come questo

cache.maxMemoryElements="2000" 

e poi nel file cacheConfig.xml attuale questo è

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

in modo che gli elementi che non vogliamo il cliente a ch ange non sono esposti. Naturalmente i dettagli di cui sopra sono solo parzialmente dettagliati e NON funzionanti. Attualmente vedo questo nel file di registro

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". 

Grazie in anticipo ...

risposta

12

L'esempio utilizza EhCacheManagerFactoryBean per esporre un riferimento allo CacheManager, con cache definite nel file cacheConfig.xml esterno. Come ha sottolineato @ ChssPly76, il risolutore di proprietà di Spring funziona solo all'interno dei propri file di definizione dei bean di Spring.

Tuttavia, non è necessario definire i singoli cache nel file esterno, è possibile definire a destra all'interno del file di definizione bean Spring, utilizzando EhCacheFactoryBean:

FactoryBean che crea un nome EHCache Cache esempio ... Se il specificato il nome della cache non è configurato nel descrittore di configurazione della cache , questo FactoryBean sarà costruire un'istanza di una cache con il nome fornito e le proprietà della cache specificate e inserirlo al CacheManager per il successivo recupero.

In altre parole, se si utilizza EhCacheFactoryBean per riferirsi a una cache di nome che non è già definito in cacheConfig.xml, poi di Primavera sarà creare e configurare una nuova istanza di cache e registrarlo con il CacheManager in fase di esecuzione.Che include specificando le cose come maxElementsInMemory, e perché questo verrebbe specificato nel file di definizione bean Spring, si ottiene il pieno sostegno del resolver immobile:

<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

Grazie! Questo mi fa superare la gobba tanto che posso arrivare al punto che mi piacerebbe. –

+3

Cosa succede se si desidera configurare qualcosa che non è una cache? Ad esempio, una proprietà di cacheManagerPeerListenerFactory? –

3

questo non è come funziona PropertyPlaceholderConfigurer. Può essere utilizzato per sostituire i valori all'interno del contesto, ma non all'interno di file esterni arbitrari. E cacheConfig.xml è un file esterno - è appena passato da Spring a EH Cache.

2

Se si utilizza Maven o Ant, entrambi offrono la possibilità di filtrare i token nei file di risorse.

Per Maven, si potrebbe fare qualcosa di simile

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

E in un file di filtro, o in POM per sé, hanno

cache.maxMemoryElements = 200 

Resource Filtering in Maven: The Definitive Guide

Con Ant, si esegue questa operazione con FilterSets e l'attività <copy>.

+1

+1, ma cosa importante tenere presente qui è che sia la sostituzione delle proprietà di Ant che di Maven avviene durante ** il tempo di compilazione ** rispetto al segnaposto di proprietà di Spring dove accade durante il runtime. – ChssPly76

+0

Sì, ottimo punto –

2

Per chiunque abbia necessità di modificare il percorso diskstore che non può essere impostato come l'ehcache javadoc afferma che il parametro diskstore viene ignorato, è possibile creare la propria implementazione di un EhCacheManagerFactoryBean, che consente di iniettare il percorso del diskstore; è fondamentalmente necessario intercettare la creazione del CacheManager e modificare la configurazione passava usando la vostra proprietà diskstore, ad esempio:

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; 
} 

La configurazione di primavera si presenta quindi come questo:

<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

solo per aggiungere a questo per me un post utile: se è necessario accedere a una proprietà jndi, è possibile impostarlo tramite: Martin

Problemi correlati