I have an application in which I use spring 3.0.2 and ibatis. Now, I need to integrate ehcache with my code. I tried this link but couldnt get it working. I would prefer someone to give me the details of the jars required, xml configurations to be done and code changes if required.
Upgrade to the latest spring 3.1 milestone - it has built-in cache support through annotations - see here
Apart from that, you can always use the EhCacheFactoryBean
To implement this in your application, follow these steps:
Step 1:
Add the jars to your application as listed on the Ehcache Annotations for Spring project site.
Step 2:
Add the Annotation to methods you would like to cache. Lets assume you are using the Dog getDog(String name) method from above:
#Cacheable(name="getDog")
Dog getDog(String name)
{
....
}
Step 3:
Configure Spring. You must add the following to your Spring configuration file in the beans declaration section:
<ehcache:annotation-driven cache-manager="ehCacheManager" />
Please refer to Ehcache site for complete details.
To integrate Ehcache just follow below steps
1 - Add Dependency in pom XML file
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.6.9</version>
</dependency>
2 - create an xml file called spring-cache.xml put it in the resources folder
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p" xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd">
<cache:annotation-driven/>
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
<property name="cacheManager" ref="ehcache" />
</bean>
<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:ehcache.xml" />
</bean>
</beans>
3 - as you can see we are using reference of ehcache.xml so create file and put it in resources folder
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd" updateCheck="true"
monitoring="autodetect" dynamicConfig="true">
<cache name="users" maxEntriesLocalHeap="5000"
maxEntriesLocalDisk="1000" eternal="false" diskSpoolBufferSizeMB="20"
timeToIdleSeconds="200" timeToLiveSeconds="500"
memoryStoreEvictionPolicy="LFU" transactionalMode="off">
<persistence strategy="localTempSwap" />
</cache>
</ehcache>
so can see create a cache for "users" so that can use wherever user list is queried from the database
4 - use it like below code
#Cacheable(value="users")
public List<User> userList() {
return userDao.findAll();
}
so that's it the same way you can implement cache wherever is required
still have some doubt or confusion see live demo
Integrate EhCache in Spring MVC
Related
I'm integrating Caching into my web application but for some reason Application Context failed to load when adding the #Cacheable annotation.
I have been trying to solve the issue for two days now, your help is really appreciated!
app.context.xml
<cache:annotation-driven cache-manager="EhCacheManagerBean" key-generator="customKeyGenerator" />
<bean id="EhCacheManagerBean" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cache-manager-ref="ehcacheBean" />
<bean id="ehcacheBean" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:configLocation="classpath:EhCache.xml" p:shared="true" />
<bean id ="customKeyGenerator" class="com.app.site.v2.cache.customKeyGenerator"/>
<bean id="siteService" class="com.app.site.v2.SiteService" primary="true"/>
EhCache.xml
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
updateCheck="true"
monitoring="autodetect"
dynamicConfig="true">
<diskStore path="java.io.tmpdir" />
<cache name="cacheSite"
maxEntriesLocalHeap="100"
maxEntriesLocalDisk="1000"
eternal="false"
timeToIdleSeconds="300"
timeToLiveSeconds="600"
memoryStoreEvictionPolicy="LFU"
transactionalMode="off">
<persistence strategy="localTempSwap" />
</cache>
Method that is being cached
public class SiteService implements ISiteService {
#Cacheable("cacheSite")
public JsonObject getSiteJson(String siteId, boolean istTranslated) { ... }
}
Exception that is being thrown
org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'siteService' is expected to be of type 'com.app.site.v2.SiteService' but was actually of type 'com.sun.proxy.$Proxy57'
The comment of #yegdom is actually the right answer. When adding the Cacheable annotation, Spring generates a proxy which implements ISiteService. And somewhere in your code, you have a bean requiring SiteService, the implementation.
There are three solutions (in preference order):
Remove the useless interface... A single implementation is just adding complexity for no direct benefit. Removing it will force Spring to use a class proxy
Fix your dependency to use ISiteService
Add proxy-target-class="true" to cache:annotation-driven to tell Spring to create a class proxy
I really do not recommend the last one since you should always depend on the interface or always depend on the class (and delete the interface). Not both at the same time.
I am interested to know the classes used in spring integration tag so that I can get more details of the tags by going through the javadoc of the classes.
I have two basic questions:
Do the spring integration xml tags (for example stdin-channel-adapter) convert to <bean class=".." /> tags?
how to figure out the bean class associated with the spring integration tags?
Here is a simple example of spring integration xml context file:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-stream="http://www.springframework.org/schema/integration/stream"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-4.0.xsd
http://www.springframework.org/schema/integration/stream http://www.springframework.org/schema/integration/stream/spring-integration-stream-4.0.xsd">
<int-stream:stdin-channel-adapter id="producer" channel="messageChannel" />
<int:poller id="defaultPoller" default="true" max-messages-per-poll="2" fixed-rate="100" />
<int-stream:stdout-channel-adapter id="consumer" channel="messageChannel" append-newline="true" />
<int:channel id="messageChannel" />
</beans>
Thanks
I think you have some mistake in your first question. See Andreas' comment.
Anyway the answer for you is like.
Any custom tags in Spring are handler by the particular NamespaceHandler. Typically you can find the target impl in file like META-INF/spring.handlers in the particular Spring jar, e.g.:
http\://www.springframework.org/schema/integration/stream=org.springframework.integration.stream.config.StreamNamespaceHandler
With that in hands you can find the code like:
this.registerBeanDefinitionParser("stdin-channel-adapter", new ConsoleInboundChannelAdapterParser());
Where you can determine that a ConsoleInboundChannelAdapterParser is responsible for parsing and instantiation beans for <stdin-channel-adapter> tag.
And there you can find the code like:
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(
"org.springframework.integration.stream.CharacterStreamReadingMessageSource");
So, the real class for target bean instance is CharacterStreamReadingMessageSource. But that's not all.
Please, look here for the design and model: http://docs.spring.io/spring-integration/docs/4.3.0.RELEASE/reference/html/overview.html#programming-tips
I have Redis installed on my machine and I am using a Jedis client within my Spring app to write some data onto Redis. For certain reasons, with each write, the number of connections to Redis keep piling up until I get a JedisConnectionFailureException.
My Spring Jedis Config file looks like this :
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Redis conection factory configurations -->
<bean id="redisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:host-name="${redis.host}"
p:port="${redis.port}"
p:password="${redis.password}"
p:use-pool="true" />
<!-- Redis String Serializer -->
<bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
<!-- JDK Serialization Redis Serializer -->
<bean id="jdkSerializationRedisSerializer" class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
<!-- Configuring the Redis Template -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"
p:connection-factory-ref="redisConnectionFactory"
p:keySerializer-ref="stringRedisSerializer"
p:valueSerializer-ref="jdkSerializationRedisSerializer" />
Within my entire app, this is the only place where I'm creating connections.
In my spring-app, I'm using the connections as follows :
redisTemplate.opsForValue().set("key", "value");
The issue is around wrong Spring Data Redis TX Sync algorithm - it has bugs.
It has been fixed and is available since Spring Data Redis 1.3 GA
im using spring for my java web app. the site has got bigger and i would like to set some configurations.
i have been researching and came across things like document builder factory, replacing spring xml with java config and others. i dunno where to start.
im thinking of implementing the configurations in xml (WEB/newConfig.xml) and have it read by the java beans. basically i wanna input my cofiguration values into xml and have it load by a java bean so that i can use it in controllers and jstl.
im just giving some examples here. for example xml configurations:
<property name="numberOfCars" value="3" />
<property name="webSiteName" value="New Spring Web App" />
....
and i read it in my java class:
class Config {
public getNumberOfCars() {
return numOfCars;
}
public getWebSiteName() {
return webSiteName;
}
}
where should i start and what online materials can i read?
==============================
update
here is what i have created.
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<context:property-placeholder location="/WEB-INF/your_prop_file.properties" />
<bean id="ConfigMgr" class="org.domain.class.ConfigMgr">
<property name="username" value="${username}">
</bean>
</beans>
you_prop_file.properties
username=hello world name
ConfigMgr.java
public class ConfigMgr {
private String username;
...getter
...setter
}
in my controller, here is what i did:
ConfigMgr config = new ConfigMgr();
sysout.out.println(config.getUsername());
i am getting null and i am sure im missing something here. where should i set the username value to the ConfigMgr class?
Spring Java configuration is a newer feature that allows you to configure your Spring application using Java classes instead of XML files. Its just an alternative for XML configuration. XML way is equally feature rich.
From what I could figure out from your problem, you want to move the hardcoded values of params (numberOfCars,webSiteName.. ) outisde your configuration file.
If that is the case, you don't have to go that far.
Just use :-
<context:property-placeholder location="classpath:your_prop_file.properties" />
in your spring xml file and replace the param values like:-
<property name="webSiteName" value="${website.name}" />
You need to have a your_prop_file.properties file in your classpath with enteries like:-
website.name=New Spring Web App
You are not injecting the ConfigMgr bean that you created in XML file.
What you are doing is you are creating a new Object in controller which does not have a clue about properties file.
Now you can inject it using either #Autowired inside your controller or through xml configuration.
There are plenty of examples available in google on basic spring dependency injection.
I'm trying to configure ehcache with openjpa. I get the following error:
org.apache.openjpa.lib.util.ParseException:
Instantiation of plugin "DataCacheManager" with value "ehcache" caused an error
"java.lang.IllegalArgumentException: java.lang.ClassNotFoundException: ehcache".
The alias or class name may have been misspelled, or the class may not have be available in the class path.
Valid aliases for this plugin are: [default]
here's my excerpt from persistence.xml:
<property name="openjpa.QueryCache" value="ehcache" />
<property name="openjpa.DataCacheManager" value="ehcache" />
here's my ehcache.xml:
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true" monitoring="autodetect" dynamicConfig="true">
<!-- -->
<cache name="openjpa" maxElementsInMemory="10000"
maxElementsOnDisk="1000" eternal="false" overflowToDisk="true"
diskSpoolBufferSizeMB="20" timeToIdleSeconds="300"
timeToLiveSeconds="600" memoryStoreEvictionPolicy="LFU"
transactionalMode="on" />
</ehcache>
And here's my pom.xml plugin dependency:
net.sf.ehcache
ehcache-openjpa
0.2.0
Is there any other way to configure openjpa+ehcache?
Yes it should work. Make sure that the ehcache-openjpa jar is on your classpath. I know this is slightly more complicated if you are running in a container environment(ie: WAS).
[update]
I know I had this working at one point and I had to do something funny with WAS shared libraries to get this to work, but I can't find any of my notes. I vaugely recollect that the problem had to do with OpenJPA not detecting Ehcache at start up, in turn we didn't register the 'ehcache' aliases.
Try configuring OpenJPA with the following properties :
<property name="openjpa.QueryCache" value="net.sf.ehcache.openjpa.datacache.EhCacheQueryCache"/>
<property name="openjpa.DataCacheManager" value="net.sf.ehcache.openjpa.datacache.EhCacheDataCacheManager"/>
<property name="openjpa.DataCache" value="net.sf.ehcache.openjpa.datacache.EhCacheDataCache"/>
<property name="openjpa.RemoteCommitProvider" value="net.sf.ehcache.openjpa.datacache.NoOpRemoteCommitProvider"/>
[/update]