Ehcache integration Spring using pages, object caching

Source: Internet
Author: User
Tags delete cache log4j

From: http://www.cnblogs.com/hoojo/archive/2012/07/12/2587556.html

Ehcache has appeared in many projects, and the usage is relatively simple. The general configuration is available, and Ehcache can cache pages, objects, and data while supporting cluster/distributed Caching. Spring's support for Ehcache is also very good if it is easy to integrate spring and Hibernate. Ehcache supports memory and disk caching, supports lru, LFU and FIFO algorithms, supports distributed cache, and can be used as a cache plugin for Hibernate. It can also provide a filter-based cache that caches the content of the response and uses GZIP compression to improve RESPONSIVENESS.

first, the preparatory work

If you have successfully added spring and Hibernate to your system, then you are ready to go to the Ehcache below.

1. Download the jar package

Ehcache object, Data cache: http://ehcache.org/downloads/destination?name=ehcache-core-2.5.2-distribution.tar.gz&bucket =tcdistributions&file=ehcache-core-2.5.2-distribution.tar.gz

Web page cache: http://ehcache.org/downloads/destination?name=ehcache-web-2.0.4-distribution.tar.gz&bucket= Tcdistributions&file=ehcache-web-2.0.4-distribution.tar.gz

2, need to add the following jar package to the Lib directory

Ehcache-core-2.5.2.jar

Ehcache-web-2.0.4.jar primarily for page caching

3, the current project src directory to add the configuration file

Ehcache.xml

Ehcache.xsd

These configuration files can be found in the Ehcache-core jar Package.

Ii. Basic usage of Ehcache
CacheManager CacheManager = cachemanager.create ();
Or
CacheManager = Cachemanager.getinstance ();
Or
CacheManager = Cachemanager.create ("/config/ehcache.xml");
Or
CacheManager = Cachemanager.create ("http://localhost:8080/test/ehcache.xml");
CacheManager = Cachemanager.newinstance ("/config/ehcache.xml");
// .......
Get a cache in the Ehcache configuration file
Cache sample = Cachemanager.getcache ("sample");
Get page Cache
Blockingcache cache = new Blockingcache (cachemanager.getehcache ("simplepagecachingfilter"));
Adding data to the cache
element element = new element ("key", "val");
Sample.put (element);
Gets the objects in the cache, note the objects to be added to the cache to serialize the implementation of the Serializable interface
Element result = Sample.get ("key");
Delete Cache
Sample.remove ("key");
Sample.removeall ();
Gets the cache configuration name in the cache manager
For (String cacheName:cacheManager.getCacheNames ()) {
    System.out.println (cachename);
}
Get all the cached objects
For (Object Key:cache.getKeys ()) {
    System.out.println (key);
}
Get the number of objects in the cache
Cache.getsize ();
Gets the size of the cache object consuming memory
Cache.getmemorystoresize ();
Get hit count of cache reads
Cache.getstatistics (). getcachehits ();
Get the number of missed cache reads
Cache.getstatistics (). getcachemisses ();
third, Page Cache

The page cache uses the filter filter to filter the requested url, if the URL appears in the Cache. The page data is then fetched from the cache object and returned with Gzip Compression. Its speed is 3-5 times the speed without compressing the cache, the efficiency is quite high! Where the page cache filter has cachingfilter, generally to extend the filter or custom filter inherit the Cachingfilter.

The Cachingfilter feature can cache the contents of an HTTP Response. This way, the granularity of the cached data is coarse, such as caching the entire page. Its advantages are simple to use, high efficiency, The disadvantage is not flexible enough, the degree of reusability is not high.

Ehcache uses the Simplepagecachingfilter class to implement the filter Cache. This class inherits from Cachingfilter and has a default Calculatekey () method that generates the cache key, which uses the URI of the HTTP request and the query condition to form the KEY. You can also implement a filter yourself, inheriting the Cachingfilter class, and then overwrite the Calculatekey () method to generate a custom key.

Cachingfilter output data is gzip compressed based on the Accept-encoding header information sent by the Browser.

There are two issues to be aware of when using gzip compression:

1. Filter uses the system default encoding for gzip compression, and for Chinese web pages that use GBK encoding, the language of the operating system needs to be set To: Zh_cn. GBK, Otherwise there will be garbled problems.

2. By default, Cachingfilter Determines whether gzip compression is done based on the accept-encoding parameter values that are included in the request headers sent by the Browser. Although the Ie6/7 browser supports gzip compression, It does not take this parameter when sending a Request. In order to IE6/7 can also be gzip compressed, can be inherited cachingfilter, to implement their own filter, and then in the specific implementation of the Acceptsgzipencoding method of Overwrite.

Specific implementation reference:

Protected Boolean acceptsgzipencoding (httpservletrequest Request) {

Boolean IE6 = headercontains (request, "user-agent", "MSIE 6.0");

Boolean IE7 = Headercontains (request, "user-agent", "MSIE 7.0");

return acceptsencoding (request, "gzip") | | IE6 | | ie7;

}

Add the following configuration to the Ehcache.xml

<?xml version= "1.0" encoding= "gbk"?>
<ehcache xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xsi:nonamespaceschemalocation= "ehcache.xsd" >
    <diskstore path= "java.io.tmpdir"/>
    <defaultcache maxelementsinmemory= "10000" eternal= "false" timetoidleseconds= "+" timetoliveseconds= "30" overflowtodisk= "false"/>
    
        Configuring Custom Caches
        Maxelementsinmemory: Maximum number of objects allowed to be created in cache
        Eternal: whether the object in the cache is permanent, and if so, the timeout setting is ignored and the object never Expires.
        Timetoidleseconds: the passivation time of cached data, that is, before an element dies,
                    The maximum time interval value for two access times, which can only be valid if the element is not permanently resident.
                    If the value is 0, it means that the element can pause for an infinite amount of time.
        Timetoliveseconds: the lifetime of the cached data, which is the maximum time interval value of an element from build to Extinction.
                    This can only be valid if the element is not permanently resident, and if the value is 0, it means that the element can pause for an infinite amount of time.
        Overflowtodisk: If the disk cache is enabled when there is not enough memory.
        Memorystoreevictionpolicy: Cache is full after the elimination algorithm.
    -
    
        
        Eternal= "false"
        
        
        timetoliveseconds= "1800"
        memorystoreevictionpolicy= "LFU"/>
</ehcache>

Specific code:

Package com.hoo.ehcache.filter;
Import java.util.Enumeration;
Import javax.servlet.FilterChain;
Import javax.servlet.http.HttpServletRequest;
Import javax.servlet.http.HttpServletResponse;
Import net.sf.ehcache.CacheException;
Import net.sf.ehcache.constructs.blocking.LockTimeoutException;
Import net.sf.ehcache.constructs.web.AlreadyCommittedException;
Import net.sf.ehcache.constructs.web.AlreadyGzippedException;
Import net.sf.ehcache.constructs.web.filter.FilterNonReentrantException;
Import net.sf.ehcache.constructs.web.filter.SimplePageCachingFilter;
Import org.apache.commons.lang.StringUtils;
Import org.apache.log4j.Logger;
/**
* <b>function:</b> Mobile Page Cache filter
* @author Hoojo
* @createDate 2012-7-4 09:34:30
* @file Pageehcachefilter.java
* @package Com.hoo.ehcache.filter
* @project Ehcache
* @blog Http://blog.csdn.net/IBM_hoojo
* @email [email protected]
* @version 1.0
*/
public class Pageehcachefilter extends Simplepagecachingfilter {
    Private final static Logger log = Logger.getlogger (pageehcachefilter.class);
    
    Private final static String Filter_url_patterns = "PATTERNS";
    private static string[] cacheurls;
    
    private void init () throws cacheexception {
        String patterns = Filterconfig.getinitparameter (filter_url_patterns);
        Cacheurls = Stringutils.split (patterns, ",");
    }
    
    @Override
    protected void DoFilter (final httpservletrequest request,
            Final HttpServletResponse response, final Filterchain Chain)
            Throws alreadygzippedexception, alreadycommittedexception,
            filternonreentrantexception, locktimeoutexception, Exception {
        if (cacheurls = = Null) {
            Init ();
        }
        
        String url = Request.getrequesturi ();
        Boolean flag = false;
        If (cacheurls! = null && cacheurls.length > 0) {
            For (String Cacheurl:cacheurls) {
                If (url.contains (cacheurl.trim ())) {
                    Flag = true;
                    Break
                }
            }
        }
        If we cache the page with the URL we want to cache, we will perform a normal page turn
        If (flag) {
            String query = request.getquerystring ();
            If (query! = Null) {
                query = "?" + query;
            }
            Log.info ("current request is cached:" + URL + query);
            Super.dofilter (request, response, chain);
        } else {
            Chain.dofilter (request, response);
        }
    }
    
    @SuppressWarnings ("unchecked")
    Private Boolean headercontains (final httpservletrequest request, final string header, final string Value) {
        Logrequestheaders (request);
        Final enumeration accepted = Request.getheaders (header);
        While (accepted.hasmoreelements ()) {
            Final String headervalue = (string) accepted.nextelement ();
            If (headervalue.indexof (value)! =-1) {
                Return true;
            }
        }
        Return false;
    }
    
    /**
     * @see net.sf.ehcache.constructs.web.filter.filter#acceptsgzipencoding (javax.servlet.http.HttpServletRequest)
     * <b>function:</b> compatible IE6/7 gzip compression
     * @author Hoojo
     * @createDate 2012-7-4 11:07:11
     */
    @Override
    Protected Boolean acceptsgzipencoding (httpservletrequest Request) {
        Boolean IE6 = headercontains (request, "user-agent", "MSIE 6.0");
        Boolean IE7 = Headercontains (request, "user-agent", "MSIE 7.0");
        return acceptsencoding (request, "gzip") | | IE6 | | ie7;
    }
}

Here Pageehcachefilter inherited the simplepagecachingfilter, generally simplepagecachingfilter is enough, here is to meet the current system needs to do the cover Operation. Using simplepagecachingfilter requires configuring Cachename,cachename in Web. XML by default simplepagecachingfilter, corresponding to the cache configuration in Ehcache.xml.

Add the following configuration to Web. XML

<!--cache, gzip Compress Core filters--
<filter>
    <filter-name>PageEhCacheFilter</filter-name>
    <filter-class>com.hoo.ehcache.filter.PageEhCacheFilter</filter-class>
    <init-param>
        <param-name>patterns</param-name>
        <!--configure the URL you need to cache--
        <param-value>/cache.jsp, product.action, market.action </param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>PageEhCacheFilter</filter-name>
    <url-pattern>*.action</url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>PageEhCacheFilter</filter-name>
    <url-pattern>*.jsp</url-pattern>
</filter-mapping>

When these pages are first requested, the pages are added to the cache, and later requests for those pages are taken from the Cache. You can test whether the page is cached by using a little foot in the cache.jsp page. <%=new Date ()%> If the time is variable, it means that the page is not cached or the cache has expired, otherwise it is in the cache State.

four, Object Cache

Object caching is to add the query data to the cache, the next time you query again directly from the cache, rather than go to the database query.

Object caching is generally for methods, classes, and the combination of Spring's AOP objects, method caching is Simple. There is a need for cutting programming, using spring methodinterceptor or using @aspect.

The code is as Follows:

Package com.hoo.common.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.apache.log4j.Logger;
Import org.springframework.beans.factory.InitializingBean;
/**
* @author Hoojo
* @createDate 2012-7-2 06:05:34
* @file Methodcacheinterceptor.java
* @package Com.hoo.common.ehcache
* @project Ehcache
* @blog Http://blog.csdn.net/IBM_hoojo
* @email [email protected]
* @version 1.0
*/
public class Methodcacheinterceptor implements methodinterceptor, Initializingbean {
    Private static final Logger log = Logger.getlogger (methodcacheinterceptor.class);
    
    Private Cache cache;
    public void Setcache (cache Cache) {
        This.cache = cache;
    }
    public void Afterpropertiesset () throws Exception {
        Log.info (cache + "A cache is Required. Use Setcache (Cache) to provide One. ");
    }
    Public Object invoke (methodinvocation Invocation) throws Throwable {
        String targetName = invocation.getthis (). getclass (). getName ();
        String methodName = Invocation.getmethod (). getName ();
        object[] arguments = invocation.getarguments ();
        Object result;
        String CacheKey = Getcachekey (targetName, methodName, arguments);
        Element element = null;
        Synchronized (this) {
            element = Cache.get (cacheKey);
            if (element = = Null) {
                Log.info (cacheKey + "add to cache:" + cache.getname ());
                Invoke the actual method
                result = Invocation.proceed ();
                element = new element (cacheKey, (Serializable) result);
                Cache.put (element);
            } else {
                Log.info (cacheKey + "use cache:" + cache.getname ());
            }
        }
        return Element.getvalue ();
    }
    /**
     * <b>function:</b> return specific method full path name parameter
     * @author Hoojo
     * @createDate 2012-7-2 06:12:39
     * @param targetName Full path
     * @param MethodName Method Name
     * @param arguments parameters
     * @return Full method name
     */
    private string Getcachekey (string targetName, string methodName, object[] arguments) {
        StringBuffer sb = new 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 ();
    }
}

The method interceptor here is primarily to intercept the method of the class you want to intercept, and then determine if the Method's Classpath + method name + parameter value combination of the cache key exists in the cached Caches. If it exists, remove the object from the cache and convert it to the return type we Want. If not, add the object returned by the method to the Cache. The idea is that the parameters of the current method and the object type of the return value need to be serialized.

We need to add Applicationcontext.xml in the SRC directory to complete the configuration of the Methodcacheinterceptor interceptor, which is the idea of injecting our cache object, which cache to manage the object cache, and then which classes, method to participate in the scanning of the Interceptor.

Add the following configuration:

<!--configuring EH Cache manager--
<bean id= "cachemanager" class= "org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>
<!--configure a simple cache factory bean object--
<bean id= "simplecache" class= "org.springframework.cache.ehcache.EhCacheFactoryBean" >
    <property name= "cachemanager" ref= "cachemanager"/>
    <!--cache configuration with cache affinity Ehcache.xml
    <property name= "cachename" value= "mobilecache"/>
</bean>
<!--configure a cache Interceptor object to handle the specific cache business--
<bean id= "methodcacheinterceptor" class= "com. hoo.common.interceptor.MethodCacheInterceptor" >
    <property name= "cache" ref= "simplecache"/>
</bean>
<!--the Pointcut object participating in the cache (pointcut object, determining when and where to call the interceptor)--
<bean id= "methodcachepointcut" class= "org.springframework.aop.support.RegexpMethodPointcutAdvisor" >
    <!--configuring the Cache AOP facets--
    <property name= "advice" ref= "methodcacheinterceptor"/>
    <!--configure which methods participate in the cache policy--
    <!--  
        . Indicates compliance with any single character                  
        # # #  + indicates that the previous character matches one or more times                  
        # # #  * Indicates a previous character 0 or more times                  
        # # #  \escape symbols used by any regular expression                  
    -                 
    <!--. * indicates that the preceding prefix (including the package Name) represents the print method--
    <property name= "patterns" >
        <list>
            <value>com.hoo.rest.*RestService*\.*get.*</value>
            <value>com.hoo.rest.*RestService*\.*search.*</value>
        </list>
    </property>
</bean>

Add the following cache configuration in Ehcache.xml

<cache name= "mobilecache"
        maxelementsinmemory= "10000"
        Eternal= "false"
        overflowtodisk= "true"
        timetoidleseconds= "1800"
        timetoliveseconds= "3600"
        memorystoreevictionpolicy= "LFU"/>

Ehcache integration Spring using pages, object caching

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.