Spring aopはredisキャッシュをします

9184 ワード

実際の開発では統一的なキャッシュ処理は必要ありません.一部の機能でキャッシュ処理を追加するだけで、後期の開発で追加する必要があります.ここではspring aopを利用してカットポイントとしてキャッシュ処理に参加することを提供します.キャッシュを追加する必要がある場所に注釈で追加するだけでよい
ステップ1:カスタムインキャッシュ注記を追加する
package com.izhbg.typz.base.common.redis;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 *     
 * 
 * 
 */
@Retention(RetentionPolicy.RUNTIME)  
@Target({ElementType.METHOD})  
public @interface RedisCache {  
    public String fieldKey(); //  key  
    public Class type();//  
    public int expire() default 0;      //     ,       
}

ステップ2:カスタム削除キャッシュ注記を追加する
package com.izhbg.typz.base.common.redis;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 *     
 * 
 * 
 */
@Retention(RetentionPolicy.RUNTIME)  
@Target({ElementType.METHOD})  
public @interface RedisEvict {  
    public String fieldKey(); //  key  
    public Class type();//  
}

ステップ3:キャッシュ・カットの追加
package com.izhbg.typz.base.common.redis;

import java.lang.reflect.Method;
import java.util.List;

import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.StringRedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
/**
 * redis    
* @ClassName: CacheAspect 
* @author caixl 
* @date 2016-6-14   10:14:08 
*
 */
@Component
@Aspect
public class CacheAspect {

	public static final Logger infoLog = Logger.getLogger(CacheAspect.class);

	@Autowired
	private RedisTemplate redisTemplate;

	/**
	 *        
	 * @param jp
	 * @param cache
	 * @return
	 * @throws Throwable
	 */
	@SuppressWarnings("unchecked")
	@Around("@annotation(com.izhbg.typz.base.common.redis.RedisCache)")
	public Object RedisCache(final ProceedingJoinPoint jp)
			throws Throwable {
		Method method=getMethod(jp);
		RedisCache cache = method.getAnnotation(RedisCache.class);
		//     、      
		Object[] args = jp.getArgs();
		
		
		//     ,        key
		final String key = parseKey(cache.fieldKey(),method,jp.getArgs());
		if (infoLog.isDebugEnabled()) {
			infoLog.debug("  key:" + key);
		}

		//         
		//Method me = ((MethodSignature) jp.getSignature()).getMethod();
		//             
		Class modelType = method.getAnnotation(RedisCache.class).type();

		//   redis      
		String value = (String) redisTemplate.opsForHash().get(
				modelType.getName(), key);

		// result          
		Object result = null;
		if (null == value) {
			//      
			if (infoLog.isDebugEnabled()) {
				infoLog.debug("     ");
			}

			//          
			result = jp.proceed(args);

			//        
			final String  json = serialize(result);
			final String hashName = modelType.getName();
			final int expire = cache.expire();
			//          
			/*redisTemplate.execute(new RedisCallback() {
                @Override
                public Object doInRedis(RedisConnection redisConn) throws DataAccessException {
                    //             String     
                    //                 
                    StringRedisConnection conn = (StringRedisConnection) redisConn;

                    //   hash     
                    //      ,   hash       
                    if (false == conn.exists(hashName) ){
                        conn.hSet(hashName, key, json);
                        conn.expire(hashName, expire);
                    } else {
                        conn.hSet(hashName, key, json);
                    }

                    return null;
                }
            });*/
			//          
			redisTemplate.opsForHash().put(modelType.getName(), key, json);
		} else {
			//     
			if (infoLog.isDebugEnabled()) {
				infoLog.debug("    , value = " + value);
			}

			//              
			Class returnType = ((MethodSignature) jp.getSignature())
					.getReturnType();

			//            json
			result = deserialize(value, returnType, modelType);

			if (infoLog.isDebugEnabled()) {
				infoLog.debug("       = {}" + result);
			}
		}

		return result;
	}
	/**
	 *     
	 * @param jp
	 * @param cache
	 * @return
	 * @throws Throwable
	 */
	@Around("@annotation(com.izhbg.typz.base.common.redis.RedisEvict)")
	public Object RedisEvict(final ProceedingJoinPoint jp)
			throws Throwable {
		//         
		Method me = ((MethodSignature) jp.getSignature()).getMethod();
		//             
		Class modelType = me.getAnnotation(RedisEvict.class).type();

		if (infoLog.isDebugEnabled()) {
			infoLog.debug("    :" + modelType.getName());
		}
		//       
	/*	redisTemplate.opsForHash().delete(paramH, paramArrayOfObject);*/
		redisTemplate.delete(modelType.getName());

		return jp.proceed(jp.getArgs());
	}
	 /**
     *           
     *  
     *  MethodSignature.getMethod()                  
     *	              
     *                     
     */
    public Method getMethod(ProceedingJoinPoint pjp){
      //       
      Object [] args=pjp.getArgs();
      Class [] argTypes=new Class[pjp.getArgs().length];
      for(int i=0;i

ステップ3:使用方法:
@Override
	@RedisCache(type=TXtYh.class,fieldKey="#yhId")
	public TXtYh findByYhId(String yhId) throws Exception {
		if(StringHelper.isEmpty(yhId))
			throw new ServiceException("    ,        ");
		return tXtYhManager.findUniqueBy("yhId", yhId);
	}
@Override
	@RedisEvict(type=TXtYh.class,fieldKey="#yhIds")
	public void deleteByIds(String[] yhIds) throws Exception {
		if(yhIds==null||yhIds.length<=0)
			throw new ServiceException("    ,        ");

redis構成を添付: