2009-10-07 8 views
7

J'ai un fichier xml contexte du printemps avec cetteSpring contexte configuration ehcahe propriété de placholder

<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'objectif est de permettre au client de modifier le fichier de propriétés, comme celui-ci

cache.maxMemoryElements="2000" 

puis dans le fichier cacheConfig.xml réel avoir ce

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

afin que les articles que nous ne voulons pas que le client ch ange ne sont pas exposés. Bien sûr, les détails ci-dessus ne sont que partiellement détaillés et ne fonctionnent pas. À l'heure actuelle, je vois cela dans le fichier journal

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

Merci à l'avance ...

Répondre

12

Votre exemple utilise EhCacheManagerFactoryBean pour exposer une référence au CacheManager, avec des antémémoires définies dans le fichier externe cacheConfig.xml. Comme l'a souligné @ ChssPly76, le résolveur de propriétés de Spring ne fonctionne que dans les fichiers de définition de bean de Spring.

Cependant, vous ne devez pas définir les caches individuels dans le fichier externe, vous pouvez les définir à droite dans le fichier de définition de grain de printemps, en utilisant EhCacheFactoryBean:

FactoryBean qui crée un nom EHCache Cache par exemple ... Si le spécifié cache nommé n'est pas configuré dans le descripteur de configuration de cache , ce FactoryBean va construire une instance d'un cache avec le nom fourni et les propriétés spécifiées du cache et l'ajouter à la CacheManager pour récupération ultérieure.

En d'autres termes, si vous utilisez EhCacheFactoryBean de se référer à un cache nommé qui n'est pas déjà défini dans cacheConfig.xml, puis Spring va créer et configurer une nouvelle instance de cache et l'enregistrer avec l'CacheManager lors de l'exécution.Cela comprend la spécification des choses comme maxElementsInMemory, et parce que cela serait spécifié dans le fichier de définition de bean Spring, vous obtenez le soutien complet du résolveur de la propriété:

<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

Merci! Cela me dépasse assez pour que je puisse arriver au point que je voudrais. –

+3

Que faire si vous voulez configurer quelque chose qui n'est pas un cache? Par exemple, une propriété de cacheManagerPeerListenerFactory? –

3

Ce n'est pas comment fonctionne PropertyPlaceholderConfigurer. Il peut être utilisé pour remplacer les valeurs dans le contexte, mais pas dans des fichiers externes arbitraires. Et cacheConfig.xml est un fichier externe - il est juste passé par Spring à EH Cache.

2

Si vous utilisez Maven ou Ant, les deux offrent la possibilité de filtrer les jetons dans les fichiers de ressources.

Pour Maven, vous pouvez faire quelque chose comme

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

Et dans un fichier de filtre, ou dans le POM lui-même, avez

cache.maxMemoryElements = 200 

Resource Filtering in Maven: The Definitive Guide

Avec Ant, vous le faites avec FilterSets et la tâche <copy>.

+1

+1, mais important à garder à l'esprit ici, c'est qu'avec les propriétés Ant et Maven, le remplacement des propriétés se produit pendant le ** temps de construction **, contrairement à l'espace réservé de propriété de Spring, où cela se produit pendant l'exécution. – ChssPly76

+0

Oui, bon point –

2

Pour toute personne qui a besoin de modifier le chemin de diskstore qui ne peut pas être défini comme l'ehcache javadoc indique que le paramètre diskstore est ignoré, vous pouvez créer votre propre implémentation d'un EhCacheManagerFactoryBean, ce qui vous permet d'injecter le chemin du diskstore; vous avez besoin essentiellement d'intercepter la création du CacheManager et modifier la configuration passée le long en utilisant votre propriété diskstore, par exemple:

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 configuration Spring ressemble alors à ceci:

<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

juste pour ajouter à ce poste utile: si vous avez besoin d'accéder à une propriété jndi, vous pouvez le définir via: Martin

Questions connexes