Abstract: mainly for the DAO layer of some database query operation, the data is not strong real-time, directly into the cache. When it is in the cache, the data in the cache is used. Such a method is eventually implemented using only one annotation. For the previous Hibernate level two cache use, it is quite strange. For example, if you support Redis or you can develop your own support. Support for partial caching of the method configuration is supported, not all hibernate entities are added to the cache. Maybe my method for the level two cache, the code gap aside, is also the same thing.
In these days of work, suddenly encountered for some of the entity classes, need to be cached. But the number of these entity classes is huge, and it is too time-consuming to initialize the load. So the initial solution is to check the cache first, the cache does not query the database, check out the database and then put into the cache. It is also convenient to set the expiration time.
But for the current project, DAO is as independent maven Module,redis is also independent maven Module, the code becomes difficult to maintain, the structure is not clear. So the annotations are introduced, and in the Redis project, AOP is done for annotations, so that no cached items can be ignored. If it is used, it can be automatically added to the cache.
Comment Code:
Packagecom.ns.annotation;Importjava.lang.annotation.Documented;ImportJava.lang.annotation.ElementType;Importjava.lang.annotation.Retention;ImportJava.lang.annotation.RetentionPolicy;ImportJava.lang.annotation.Target;ImportJava.util.concurrent.TimeUnit;/*** can only annotate DAO inside the corresponding get method, pass the parameter as HashKey, return the value as values *@authorHan*/@Target (Elementtype.method) @Retention (retentionpolicy.runtime) @Documented Public@InterfaceCached {/*** Redis Key *@return */String key (); /*** Expiration time, default is 0 that never expires *@return */ LongTimeout ()default0L; /*** Time unit, default is seconds *@return */timeunit timeunit ()defaulttimeunit.seconds;}
AOP Tangent code
PackageCOM.NS.REDIS.AOP;ImportJava.lang.reflect.Method;ImportJava.util.HashMap;ImportJava.util.LinkedHashMap;ImportJava.util.Map;Importorg.apache.commons.collections.MapUtils;Importorg.apache.commons.lang.ArrayUtils;ImportOrg.aspectj.lang.ProceedingJoinPoint;ImportOrg.aspectj.lang.annotation.Around;ImportOrg.aspectj.lang.annotation.Aspect;ImportOrg.aspectj.lang.annotation.Pointcut;Importorg.aspectj.lang.reflect.MethodSignature;Importorg.springframework.beans.factory.annotation.Autowired;Importorg.springframework.dao.DataAccessException;Importorg.springframework.data.redis.connection.RedisConnection;ImportOrg.springframework.data.redis.core.RedisCallback;ImportOrg.springframework.data.redis.serializer.JdkSerializationRedisSerializer;ImportOrg.springframework.data.redis.serializer.RedisSerializer;Importorg.springframework.stereotype.Component;ImportOrg.springframework.util.Assert;Importcom.ns.annotation.Cached;ImportCom.ns.redis.dao.base.BaseRedisDao;/*** Getbean of DAO's cache processing *@authorHan*/@Aspect @component Public classAutorediscachedextendsBaseredisdao<string, object>{ /** Constrain any method of the class containing DAO under any package, and be cached annotated*/@Pointcut ("Execution (* *.. *dao*.* (*,..) && @annotation (com.ns.annotation.Cached)) ") Private voidCachemethod () {} @Around ("Cachemethod ()") PublicObject Doarround (Proceedingjoinpoint PJP)throwsthrowable{object[] args=Pjp.getargs (); //Defining a serializer FinalRedisserializer<string> Keyserializer =Getkeyserializer (); FinalRedisserializer<object> Hashvalueserializer =Gethashvalueserializer (); FinalRedisserializer<object> Hashkeyserializer =Gethashkeyserializer (); //serialization parameters, as HashKey byte[] hashkeybytestmp =NULL; if(Args.length = = 1) {hashkeybytestmp= Hashkeyserializer.serialize (args[0]); }Else{hashkeybytestmp=New byte[0]; for(Object Arg:args) {hashkeybytestmp=Arrayutils.addall (hashkeybytestmp, Hashkeyserializer.serialize (ARG)); } } Final byte[] Hashkeybytes =hashkeybytestmp; Methodsignature methodsignature=(methodsignature) pjp.getsignature (); Method Method=Methodsignature.getmethod (); FinalCached cacheinfo = method.getannotation (Cached.class); Object obj=NULL; Obj= Execute (NewRediscallback<object>() {@Override PublicObject Doinredis (redisconnection connection)throwsDataAccessException {byte[] tmp =Connection.hget (Keyserializer.serialize (Cacheinfo.key ()), hashkeybytes); returnhashvalueserializer.deserialize (TMP); } }); if(obj = =NULL){ FinalObject Objreturn =pjp.proceed (); if(Objreturn! =NULL) {Execute (NewRediscallback<boolean>() {@Override PublicBoolean Doinredis (redisconnection connection)throwsDataAccessException {returnConnection.hset (Keyserializer.serialize (Cacheinfo.key ()), Hashkeybytes,hashvalueserializer.serialize ( Objreturn)); } }); if(Cacheinfo.timeout () >0) {expire (Cacheinfo.key (), Cacheinfo.timeout (), Cacheinfo.timeunit ()); }} obj=Objreturn; } //get from DAO returnobj; }}
Implementing annotations with spring Aop automatic Spring Redis cache for the DAO layer