Spring+ehcache Combat--the way of performance optimization

Source: Internet
Author: User
Tags assert throwable delete cache

In the System Integration platform project encountered a more troublesome problem, because the use of the test system is dependent on the basic system released WebService to obtain the basic data, WebService cross-network transmission itself will have a certain impact on the system performance, plus the amount of data transferred to the larger the impact on systems, but also cause the system performance degradation is a frequent open shutdown database. In response to these two issues, we have adopted two solutions to minimize the impact of performance. The first is that webservice from the original transfer serialized object to the transfer JSON string, the second is the opening and closing of the database connection to cache processing. In this paper, we mainly discuss the second solution of Ehcache.

Ehcache is a very good caching framework, configuration comes simple and powerful, in the project to cache the place there are two main, the first is the cache entity object, this layer of cache added to the physical layer, The primary use of Hibernate's Level two cache (and the need to turn on query caching) is simple with spring's AOP annotations, whereas in other query methods The main use is Ehcache, which caches the various objects returned by the method. Open Hibernate query cache and level two cache is relatively simple, here do not introduce too much, we mainly look at the use of Ehcache.

1. First we use Interceptor, which defines two interceptors methodcacheinterceptor and Methodcacheafteradvice, which are used primarily to intercept methods that start with Get and find (for caching results). The second interceptor is mainly used to intercept the method beginning with update, to clear the cache, let's look at the specific code:

public class Methodcacheinterceptor implements Methodinterceptor,initializingbean {private static final Log logger = Logf Actory.getlog (Methodcacheinterceptor.class);p rivate cache cache;public void Setcache (cache cache) {This.cache = cache;} Public Methodcacheinterceptor () {super ();} /** * Intercepts the Service/dao method and finds out if the result exists, returns the value in the cache if it exists, 31 * * Otherwise, returns the database query result and puts the query result in the cache, */public Object invoke (METHODINV Ocation invocation) throws Throwable {String targetName = Invocation.getthis (). GetClass (). GetName (); String methodName = Invocation.getmethod (). GetName (); object[] arguments = invocation.getarguments (); Object result; Logger.debug ("Find object from Cache is" + cache.getname ()); String CacheKey = Getcachekey (TargetName, methodName, arguments); Element element = Cache.get (CacheKey), if (element = = null) {Logger.debug ("hold up method, get method result and create CA Che........! "); result = Invocation.proceed (); element = new Element (CacheKey, (Serializable) result); SYSTEM.OUT.PRINTLN ("-----Lookup in non-cache, findCache "); Cache.put (element);} Else{system.out.println ("find----in----cache");} return Element.getvalue ();} /** * Method of obtaining the cache key, the cache key is the unique identifier of an element in the cache * Cache key * Includes package name + class name + method name, such as Com.co.cache.service.UserServiceImp L.getalluser */private string Getcachekey (String targetName, string methodname,object[] arguments) {StringBuffer SB = n EW StringBuffer (); Sb.append (TargetName). Append ("."). Append (MethodName); if (arguments! = null) && (arguments.length! = 0)) {for (int i = 0; i < arguments.length; I + +) {sb.append ("."). Append (Arguments[i]);}} return sb.tostring ();} /** * Implement Initializingbean, check if the cache is empty */public void Afterpropertiesset () throws Exception {Assert.notnull (Cach E, "need a cache. Please use Setcache (Cache) to create it. ");}
the code for the second interceptor is as follows:

public class Methodcacheafteradvice implements Afterreturningadvice,initializingbean {private static final Log logger = L Ogfactory.getlog (Methodcacheafteradvice.class);p rivate cache cache;public void Setcache (cache cache) {This.cache = Cache;} Public Methodcacheafteradvice () {super ();} public void afterreturning (Object arg0, Method arg1, object[] arg2,object arg3) throws Throwable {String className = Arg3. GetClass (). GetName (); List List = Cache.getkeys (); for (int i = 0; i < list.size (); i++) {String CacheKey = string.valueof (List.get (i)); if (ca Chekey.startswith (ClassName)) {cache.remove (CacheKey); SYSTEM.OUT.PRINTLN ("------Clear cache----"), Logger.debug ("Remove cache" + CacheKey);}} public void Afterpropertiesset () throws Exception {assert.notnull (cache, "need a cache. Please use Setcache (Cache) to create it. ");}
with these two interceptors, the next thing we need to do is to bring the two interceptors into the project to make it work, and these are all in the Ehcache.xml file, and here's how the file is configured:

<?xml version= "1.0" encoding= "UTF-8"?> <! DOCTYPE beans Public "-//spring//dtd bean//en" "Http://www.springframework.org/dtd/spring-beans.dtd" ><beans ><!--Reference Ehcache configuration--><bean id= "Defaultcachemanager" class= " Org.springframework.cache.ehcache.EhCacheManagerFactoryBean "><property name=" Configlocation "><value >ehcache.xml</value></property></bean><!--define the Ehcache factory and set the cache name--><bean used Id= "EhCache" class= "Org.springframework.cache.ehcache.EhCacheFactoryBean" ><property name= "CacheManager" ><ref local= "Defaultcachemanager"/></property><property name= "CacheName" ><value> default_cache</value></property></bean><!--find/create CACHE blocker--><bean id= " Methodcacheinterceptor "class=" Com.co.cache.ehcache.MethodCacheInterceptor "><property name=" cache ">< Ref local= "EhCache"/></property></bean><!--flush cache blocker--><bean id= "MethodcacheAfteradvice "class=" Com.co.cache.ehcache.MethodCacheAfterAdvice "><property name=" cache "><ref local=" EhCache "/></property></bean><bean id=" Methodcachepointcut "class=" Org.springframework.aop.support.RegexpMethodPointcutAdvisor "><property name=" advice "><ref local=" Methodcacheinterceptor "/></property><property name=" Patterns "><list><value>.*find.* </value><value>.*get.*</value></list></property></bean><bean id= " Methodcachepointcutadvice "class=" Org.springframework.aop.support.RegexpMethodPointcutAdvisor "><property Name= "Advice" ><ref local= "Methodcacheafteradvice"/></property><property name= "Patterns" > <list><value>.*create.*</value><value>.*update.*</value><value>.*delete.* </value></list></property></bean></beans>

In this way, the configuration of the interceptor and the cache configuration are introduced in the project, the cache configuration information is mainly in the Ehcache.xml file, the details are as follows:

<ehcache><diskstore path= "H:\\temp\\cache"/><defaultcache maxelementsinmemory= "eternal=" False "timetoidleseconds=" timetoliveseconds= "overflowtodisk=" true "/><cache name=" Default_cache " Maxelementsinmemory= "10000" eternal= "false" timetoidleseconds= "300000" timetoliveseconds= "600000" overflowToDisk= " True "/></ehcache>  

Now that we have the corresponding configuration is done, let us set up a test class to test whether the cache is working, here we mainly use the class has three, to see the specific code:

Public interface Testservice {public List getallobject ();p ublic void Updateobject (Object object);}
Testservice is the calling interface, and the following testserviceimpl is its implementation, the code is as follows:

public class Testserviceimpl implements Testservice {public List getallobject () {SYSTEM.OUT.PRINTLN ("--- The element does not exist within the testservice:cache and is found and put into cache! "); return null;} public void Updateobject (Object object) {System.out.println ("---testservice: Updates the object, the cache created by this class will be remove! ");}}
The following junittestclass is the real test class with the following code:

public class Junittestclass {@Testpublic void TestRun () {String default_context_file = "/ Applicationcontext.xml "; ApplicationContext context = new Classpathxmlapplicationcontext (default_context_file); Testservice Testservice = (testservice) context.getbean ("Testservice");//Find Testservice.getallobject () for the first time;// Find Testservice.getallobject () for the second time;//Execute Update method (should clear cache) Testservice.updateobject (null);// Third time find Testservice.getallobject ();}} 

Analysis of the test code, when the first time the Getallobject () method is executed because it is the first time the query operation, will be methodcacheinterceptor interception, when Methodcacheinterceptor found no hit cache, Execute the Invoke () method, let the program go to the database query (this program only simulates the database query, and does not really query the database, but it is expressed in the meaning of the query database is not different), We see that this is going to execute Testserviceimpl's Getallobject () method, print out a statement to print the "-----Non-cache lookup, find and put cache" statement in the interceptor, and when the method is executed the second time because the cache already exists, So the Testserviceimpl Getallobject () method is no longer executed, while only the "find----in----cache" statement in the interceptor is printed, when the Updateobject () is executed Method is Methodcacheafteradvice intercepted and executes the Testserviceimpl Updateobject () method, so it prints "---testservice: Updated object, this class-generated cache will be removed and the "------Delete cache----" statement in the interceptor, and when the third lookup is performed, because the cache has been cleared, this output will be the same as the first statement, and the following to verify that our speculation is correct:


The output is the same as we guessed, which means that the Ehcache cache has worked in the program at this time.

Spring+ehcache Combat--the way of performance optimization

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.