1 Ehcache Profile
EhCache is a pure Java in-process caching framework, with fast, lean and so on, is the default Cacheprovider in Hibernate.
Ehcache is a widely used open source Java distributed cache. Mainly for general-purpose caching, Java EE and lightweight containers. It features memory and disk storage, cache loaders, cache extensions, cache exception handlers, a gzip cache servlet filter, support for rest and soap APIs, and more.
Ehcache was first developed by Greg Luck in 2003. The project was purchased by terracotta in 2009. The software is still open source, but some of the new major features (for example, consistency between fast and restartable) can only be used in commercial products, such as Enterprise EHCache and BigMemory. The Wikimedia foundationannounced is currently using Ehcache technology.
Anyway, Ehcache is a good caching technique, so let's see how the spring collocation Ehcache is implemented.
2 Spring collocation Ehcache
The system results are as follows:
3 Specific Configuration Introduction
There are several parts of the combination:
Src:java code, including interceptors, calling interfaces, testing classes
Src/cache-bean.xml: Configure Ehcache, interceptors, and test-class information corresponding to the bean
Src/ehcache.xml:ehcache Cache configuration Information
Webroot/lib: Library
4 Detailed Content Introduction
4.1 src
4.1.1 Interceptor
Two interceptors were first configured in the code:
The first interceptor is:
Com.test.ehcache.CacheMethodInterceptor
The contents are as follows:
Package Com.test.ehcache;
Import java.io.Serializable;
Import Net.sf.ehcache.Cache;
Import net.sf.ehcache.Element;
Import Org.aopalliance.intercept.MethodInterceptor;
Import org.aopalliance.intercept.MethodInvocation;
Import Org.springframework.beans.factory.InitializingBean;
Import Org.springframework.util.Assert;
public class Cachemethodinterceptor implements Methodinterceptor, Initializingbean {private cache cache;
public void Setcache (cache cache) {This.cache = cache;
Public Cachemethodinterceptor () {super (); /** * Intercept the ServiceManager method, and find whether the result exists, if there is a return cache value, * Otherwise, return the database query results, and the query results into the cache/public Object invoke (Methodi
Nvocation invocation) throws Throwable {//Get class String TargetName = Invocation.getthis (). GetClass ().
Gets the method String methodname = Invocation.getmethod () for the class to intercept. GetName ();
Gets the parameters of the method of the class to intercept object[] arguments = invocation.getarguments ();
Object result; Creates a string that is used to make the key string cachekey = Getcachekey in cache (TargetName, METhodname, arguments);
Get data from cache element element = Cache.get (CacheKey);
if (element = = null) {//If there is no data in the cache, look for a non-cache, such as a database, and place the lookup into cache result = Invocation.proceed ();
Generate the key and value element that will be stored in cache = new Element (CacheKey, (Serializable) result);
SYSTEM.OUT.PRINTLN ("-----into the non-cache lookup, such as direct lookup of the database, after the lookup into the cache");
Storing key and value in cache cache.put (element);
else {//If there is data in the cache, look for cache System.out.println ("-----into the cache to find, do not look up the database, alleviate the pressure of the database");
return Element.getvalue ();
/** * Get Cache key method, cache key is a cache of the unique identifier of an element, * including package name + Class name + method name, such as: Com.test.service.TestServiceImpl.getObject * * private string Getcachekey (string targetName, String methodname, object[] arguments) {stringbuffer sb = new Stringbu
Ffer (); Sb.append (TargetName). Append (".").
Append (methodname); if ((arguments!= null) && (arguments.length!= 0)) {for (int i = 0; i < arguments.length; i++) {Sb.appen D (".").
Append (Arguments[i]);
} return sb.tostring (); }/** * Implement InitiAlizingbean, check whether the cache is empty/public void Afterpropertiesset () throws Exception {assert.notnull (cache, "Need a cache .
Please use Setcache (Cache) create it. ");}
Cachemethodinterceptor is used to intercept a method that begins with "get", noting that the interceptor is intercepted first and then executes the original calling interface.
There is also an interceptor:
Com.test.ehcache.CacheAfterReturningAdvice
Specific content:
Package Com.test.ehcache;
Import Java.lang.reflect.Method;
Import java.util.List;
Import Net.sf.ehcache.Cache;
Import Org.springframework.aop.AfterReturningAdvice;
Import Org.springframework.beans.factory.InitializingBean;
Import Org.springframework.util.Assert;
public class Cacheafterreturningadvice implements Afterreturningadvice, Initializingbean {private cache cache;
public void Setcache (cache cache) {This.cache = cache;
Public Cacheafterreturningadvice () {super (); public void Afterreturning (Object arg0, Method Arg1, object[] arg2, Object arg3) throws Throwable {String Classnam
E = Arg3.getclass (). GetName ();
List List = Cache.getkeys ();
for (int i = 0; i < list.size (); i++) {String CacheKey = string.valueof (List.get (i));
if (Cachekey.startswith (ClassName)) {cache.remove (CacheKey);
SYSTEM.OUT.PRINTLN ("-----Clear cache"); }} public void Afterpropertiesset () throws Exception {assert.notnull (cache, "Need a cache. Please use Setcache (cach(e) Create it. ");}
Cacheafterreturningadvice is used to intercept the "update" method, note that the interceptor is the first to execute the original call interface, and then intercepted.
4.1.2 Call Interface
The interface name is:
Com.test.service.ServiceManager
The specific contents are as follows:
Package com.test.service;
Import java.util.List;
Public interface ServiceManager {public
List getObject ();
public void Updateobject (object);
The implementation class name is:
Com.test.service.ServiceManagerImpl
The specific contents are as follows:
Package com.test.service;
Import java.util.ArrayList;
Import java.util.List;
public class Servicemanagerimpl implements ServiceManager {
@Override public
List getObject () {
SYSTEM.OUT.PRINTLN ("-----ServiceManager: This element is not present in cache caches, lookup database, and put into cache! ");
return null;
}
@Override public
void Updateobject (Object object) {
System.out.println (-----servicemanager: Updated object, The cache generated by this class will be remove! ");
}
}
4.1.3 Test class
The test class name is:
Com.test.service.TestMain
The specific content is:
Package com.test.service;
Import Org.springframework.context.ApplicationContext;
Import Org.springframework.context.support.ClassPathXmlApplicationContext;
public class Testmain {public
static void Main (string[] args) {
String cachestring = "/cache-bean.xml";
ApplicationContext context = new Classpathxmlapplicationcontext (
cachestring);
Gets the bean generated by the agent factory Proxyfactory to produce a blocking effect
servicemanager Testservice = (servicemanager) Context.getbean (" Proxyfactory ");
First lookup
System.out.println ("===== first Lookup");
Testservice.getobject ();
Second lookup
System.out.println ("===== second Lookup");
Testservice.getobject ();
Execute the Update method (the cache should be cleared)
System.out.println ("===== first Update");
Testservice.updateobject (null);
Third lookup
System.out.println ("===== third Lookup");
Testservice.getobject ();
}
Note here that getting the bean is a bean produced by the agent factory Proxyfactory so that there is a blocking effect.
Can be seen, in the test class set four calls, the order of execution is:
The first time to find
Second Lookup
First time update
Third Lookup
4.2 Src/cache-bean.xml
Cache-bean.xml is used to configure the beans for Ehcache, interceptors, and test class information, as follows:
<?xml version= "1.0" encoding= "UTF-8"?> <! DOCTYPE beans Public "-//spring//dtd bean//en" "Http://www.springframework.org/dtd/spring-beans.dtd" > <beans > <!--referencing ehcache configuration--> <bean id= "Defaultcachemanager" class= Anagerfactorybean "> <property name=" configlocation "> <value>ehcache.xml</value> </property > </bean> <!--define EhCache's factory and set the name of the cache used, that is, "Com.tt"--> <bean id= "EhCache" class= Amework.cache.ehcache.EhCacheFactoryBean "> <property name=" CacheManager "> <ref local=" Defaultcachemanager "/> </property> <!--cache name--> <property name=" CacheName "> <value> ;com.tt</value> </property> </bean> <!--Create a cache, query cache interceptor--> <bean id= "Cachemethodinterc Eptor "class=" Com.test.ehcache.CacheMethodInterceptor "> <property name=" Cache "> <ref local=" Ehcache "/> </property> </bean> <!--update cache, remove cache interceptor--> <bean id= "Cacheafterreturningadvice" class= "C" Om.test.ehcache.CacheAfterReturningAdvice "> <property name=" Cache "> <ref local=" Ehcache "/> </pro Perty> </bean> <!--call interface, intercepted objects--> <bean id= "ServiceManager" class= "Com.test.service.ServiceManage" Rimpl "/> <!--insert interceptors, confirm which interceptor to invoke, the feature of the method name intercepted by the interceptor, and so on, call the Interceptor Com.test.ehcache.CacheMethodInterceptor--> <bean id= "Cachepointcut" class= "Org.springframework.aop.support.RegexpMethodPointcutAdvisor" > <!--add slices, Slice is when the Print method is executed,--> <property name= "Advice" > <ref local= "cachemethodinterceptor"/> </pro
perty> <property name= "Patterns" > <list> <!--###. Represents any single character ### + indicates that one or more occurrences of the preceding character are met ### * represents the prefix (including the package name) prefixed with the previous character 0 or more times ### \escape any regular expression uses the symbol--> <!--. * indicating that the GetObject side FA--> <value>.*get.*</value> </list> </property> </bean> <!--Insert Interceptor, confirm which interceptor to call, the method name feature of Interceptor Intercept, and so on, call Interceptor Com.test.ehcache.CacheAf Terreturningadvice--> <bean id= "Cachepointcutadvice" class= " Org.springframework.aop.support.RegexpMethodPointcutAdvisor "> <property name=" Advice "> <ref local=" Cacheafterreturningadvice "/> </property> <property name=" Patterns "> <list> <!--. * Represents front Prefix (including package name), meaning Updateobject method--> <value>.*update.*</value> </list> </property> </bean&
Gt <!--agent Factory--> <bean id= "proxyfactory" class= "Org.springframework.aop.framework.ProxyFactoryBean" > <!- -Description of the calling interface Bean name--> <property name= "target" > <ref local= "ServiceManager"/> </property> <!-
-Description Interceptor Bean name--> <property name= "Interceptornames" > <list> <value>cachePointCut</value> <value>cachePointCutAdvice</value> </list> </pRoperty> </bean> </beans>
The contents of each bean are commented, and it is worth noting that the agent factory Bean is not forgotten.
4.3 src/ehcache.xml
The details for storing Ehcache cache configuration in Ehcache.xml are as follows:
<?xml version= "1.0" encoding= "UTF-8"?> <ehcache xmlns:xsi=
"Http://www.w3.org/2001/XMLSchema-instance" "Xsi:nonamespaceschemalocation=" Http://ehcache.org/ehcache.xsd >
<!--cache file location-->
<diskstore Path= "D:\\temp\\cache"/>
<defaultcache maxelementsinmemory= "1000" eternal= "false"
timetoidleseconds= "timetoliveseconds=" overflowtodisk= "true"/>
<!--defines cached file information, where "com.tt" -->
<cache name= "Com.tt maxelementsinmemory=" 10000 "eternal=" false "timetoidleseconds=" for the name of the cached file
300000 "timetoliveseconds=" 600000 "overflowtodisk=" true "/>
</ehcache>
You can see that the storage location for the cached storage is set to "D:\temp\cache" and the cache name is set to "Com.tt", as shown in the figure:
4.4 Webroot/lib
The required Java library, as detailed in the system structure at the beginning of the picture, here is slightly.
5 test
To execute the test class, the test results are as follows:
By implementing the results we can see that:
The first search was intercepted after the discovery is the first interception, there is no caching cache, so the first implementation of the original interface class, get to query the data, there may be through the database query, and then generate cache, and the query to get the data into the cache.
The second search was intercepted after the discovery of the cache, so no longer carry out the original interface class, that is, no longer query the database, directly through the cache to get query data. Of course it's just a simple print.
Then is the first update , was intercepted after the operation is to cache the data stored in the database, and will be deleted cache.
Finally, the third query , was intercepted and found that the system does not exist cache, so the implementation of the original interface class query database, create cache, and the new query to get the data into the cache. The same way as the first query.
So we've implemented the actions that spring has to do with Ehcache.
6 Attachment Source Code
The attachment source code can be obtained from my GitHub Web site.
The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.