Use Spring AOP to configure and manage your level 2 cache (ehcache)If spring + Hibernate is used in our project, we will first think of the ehcache cache tool that comes with spring, the popular Cache Policy ehcache has been integrated in spring. Currently, many cache policies such as Oscache and memcached are used. these should be the most used cache tools currently. In a framework like spring + hibernate, ehcache should be a level-2 Cache. We know that a level-1 cache is used by default in hibernate, that is, in session. The second-level cache should be within the sessionfactory range. The second-level cache does not work by default, which requires a simple configuration. Before configuration, I would like to explain that caching can theoretically improve the performance of your website system, but the premise is that you must ensure that you have a good architecture design. For example, if a single server is used for a system built with spring + hibernate, it would be better to use the ehcache of spring for second-level cache. If your system is a distributed system with multiple servers, memcached is the best choice. Generally, memcached performs caching better than ehcache and Oscache, but not all websites use memcached to get twice the result with half the effort. Although it is better, it has a premise that you have multiple servers and are distributed. In this way, memcached is used to improve the system performance. Because memcached is a "distributed" Memory Object cache system, that is, applications that do not need to be "distributed", do not need to be shared, or simply have to be small to only one server, memcached will not bring any benefits. On the contrary, it will slow down the system efficiency because resources are also required for network connections. the Oscache cache mechanism has fewer restrictions. It is similar to ehcache. Integrating ehcache in spring + hibernate requires only three simple steps. Step 1: configure the cache file ehcache. xml and put it in the src directory by default. The following is a simple configuration. <Ehcache>
<! -Set the path for creating the cached file. Data. If the path is a Java system parameter, the current virtual opportunity is assigned a value again. The following parameters are explained as follows:
User. Home-user main directory
User. dir-current working directory of the user
Java. Io. tmpdir-default temporary file path, which is in the temp directory of Tomcat -->
<Diskstore Path = "Java. Io. tmpdir"/>
<! -Default cache configuration. Cachemanager will apply these configurations to the program. The following attributes are required for defaultcache: maxinmemory-sets the maximum value of the created object in memory.
Eternal-set whether the element (in-Memory Object) resident permanently. If yes, super
Time limit and elements will never die.
Timetoidleseconds-sets the pause time before an element dies.
That is, the maximum time interval between two accesses before an element disappears.
This is only valid when the element is not permanently resident.
Setting this attribute is useless ).
If the value is 0, it means that the element can pause for an infinite period of time.
Timetoliveseconds-sets the survival time before the elements die.
That is, the maximum time interval between the construction and extinction of an element.
This is only valid when the element is not permanently resident.
Overflowtodisk-sets whether the elements can be written to the disk when the cache in the memory reaches the maxinmemory limit.
.
-->
<! -- Timetoliveseconds must be greater than or equal to timetoidleseconds by -->
<Cache name = "default_cache"
Maxelementsinmemory = "1000"
Eternal = "false"
Timetoidleseconds = "500"
Timetoliveseconds = "500"
Overflowtodisk = "true"
/>
</Ehcache> there is a default cache configuration and a self-configured cache. If the cache is not specified in the application, the default configuration attribute is used by default. Step 2: Use the powerful mechanism in spring to design AOP for aspect. to compile two class files, methodcacheafteradvice. java (mainly synchronous updates to dirty things) and methodcacheinterceptor. java (mainly uses the Interceptor to create a cache and cache the objects to be cached ). The implementation mechanism of the interceptor is actually a common filter. It works like a filter. The following are the two files.
Methodcacheinterceptor. JavaPublic class methodcacheinterceptor implements methodinterceptor,
Initializingbean {
Private Static final log logger = logfactory
. Getlog (methodcacheinterceptor. Class); Private cache; Public void setcache (Cache cache ){
This. cache = cache;
} Public methodcacheinterceptor (){
Super ();
}/**
* Intercept the service/DAO method and check whether the result exists. If yes, return the value in the cache. Otherwise, return the database query result and put the query result into the cache.
*/
Public object invoke (methodinvocation 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 );
Long starttime = system. currenttimemillis ();
If (element = NULL ){
Logger
. Debug ("Hold up method, get method result and create cache ........! ");
Result = invocation. Proceed ();
Element = new element (cachekey, (serializable) result );
Cache. Put (element );
Long endtime = system. currenttimemillis ();
The logger.info (targetname + "." + methodname + "method is called for the first time and cached. Time consumed"
+ (Endtime-starttime) + "millisecond" + "cachekey :"
+ Element. getkey ());
} Else {
Long endtime = system. currenttimemillis ();
Logger.info (targetname + "." + methodname + "results are directly called from the cache. Time consumed"
+ (Endtime-starttime) + "millisecond" + "cachekey :"
+ Element. getkey ());
}
Return element. getvalue ();
}/**
* Obtain the cache key. The cache key is the unique identifier of an element in the cache. The cache key includes the package name, class name, method name, and parameter.
*/
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 ();
}/**
* 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 .");
} This method implements two interfaces. One is methodinterceptor (method interception), which can be executed before and after the method is called. Another initializingbean (initialize bean) is mainly used to perform a simple check after the method is called. It can be written in afterpropertiesset.
Methodcacheafteradvice
. Java
Public class methodcacheafteradvice implements afterreturningadvice,
Initializingbean {
Private Static final log logger = logfactory
. Getlog (methodcacheafteradvice. Class); Private 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 (cachekey. startswith (classname )){
Cache. Remove (cachekey );
Logger. debug ("remove cache" + cachekey );
}
}
} Public void afterpropertiesset () throws exception {
Assert. notnull (cache,
"Need a cache. Please use setcache (cache) create it .");
}
}
This method ensures cache synchronization and data consistency with databases.
Step 3: Configure bean, and the applicationContext-ehcache.xml file is the description of IOC (control reversal container) in spring. The above is just a simple write of two methods, specifically what can play a role, and when it works, and how to use declarative methods (AOP) and bean combination. <? XML version = "1.0" encoding = "UTF-8"?>
<Beans xmlns = "[url] http://www.springframework.org/schema/beans#/url]"
Xmlns: xsi = "[url] http://www.w3.org/2001/xmlschema-instance#/url]"
Xsi: schemalocation = "[url] http://www.springframework.org/schema/beans#/url] [url] #"> <! -- Use beannameautoproxycreator to automatically create a transaction proxy -->
<Bean id = "transactioninterceptor"
Class = "org. springframework. transaction. Interceptor. transactioninterceptor">
<Property name = "transactionmanager">
<Ref bean = "transactionmanager"/>
</Property>
<! -- Configure transaction properties -->
<Property name = "transactionattributes">
<Props>
<Prop key = "delete *"> propagation_required </prop>
<Prop key = "Update *"> propagation_required </prop>
<Prop key = "Save *"> propagation_required </prop>
<Prop key = "find *"> propagation_required, readonly </prop>
<Prop key = "get *"> propagation_required, readonly </prop>
</Props>
</Property>
</Bean>
<! -- Reference ehcache configuration -->
<Bean id = "defaultcachemanager"
Class = "org. springframework. cache. ehcache. ehcachemanagerfactorybean">
<Property name = "configlocation">
<Value> classpath: ehcache. xml </value>
</Property>
</Bean> <! -- Define the ehcache factory and set the cache name used -->
<Bean 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 interceptor -->
<Bean id = "methodcacheinterceptor"
Class = "com. w3cs. cache. ehcache. methodcacheinterceptor">
<Property name = "cache">
<Ref local = "ehcache"/>
</Property>
</Bean>
<! -- Flush cache interceptor -->
<Bean id = "methodcacheafteradvice"
Class = "com. w3cs. 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> <! -- Automatic proxy -->
<Bean id = "autoproxy"
Class = "org. springframework. AOP. Framework. autoproxy. beannameautoproxycreator">
<! -- It can be a service or Dao layer (preferably for the service layer * Service) -->
<Property name = "beannames">
<List>
<Value> * Dao </value>
</List>
</Property>
<Property name = "interceptornames">
<List>
<Value> methodcachepointcut </value>
<Value> methodcachepointcutadvice </value>
<Value> transactioninterceptor </value>
</List>
</Property>
</Bean>
</Beans>
The above code intercepts and caches the DaO layer. It is better to intercept the DaO layer. You can refer to the specific design of your system. If there is no business layer, you can also intercept the DaO layer. The interception is configured with a regular expression. The find and get methods are only cached. If the CREATE, update, and delete methods are used, the cache is synchronized. It is best not to use cache for some frequent operations. The cache is used for operations that do not change frequently. Only three simple steps can be used to complete ehcache. Try it yourself. I have not explained the methods in detail. In fact, it is very simple. You can see it later. Sorry for the improper handling.