spring+redis+aop

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:p="http://www.springframework.org/schema/websocket"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	   http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context 
       http://www.springframework.org/schema/context/spring-context.xsd  
       http://www.springframework.org/schema/mvc 
       http://www.springframework.org/schema/mvc/spring-mvc.xsd 
       http://www.springframework.org/schema/websocket 
       http://www.springframework.org/schema/websocket/spring-websocket.xsd">
   
	<context:property-placeholder location="classpath:umclient-config.properties"/>
 	
	<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
		<property name="maxIdle" value="300" />
		<property name="maxActive" value="3000" />
		<property name="maxWait" value="10000" />
		<property name="testOnBorrow" value="true" />
	</bean>

	<bean id="connectionFactory"  class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
		<property name="hostName" value="${redis.host}" />
		<property name="port" value="${redis.port}" />
		<property name="password" value="${redis.pass}" />
		<property name="poolConfig" ref="poolConfig" />
	</bean>

	<bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
		<property name="connectionFactory" ref="connectionFactory" />
	</bean>

</beans>


public interface RedisDao {
    /**
     * 插入
     */
	boolean put(final String keyId, final String entity);
	/**
	 * 删除
	 */
	void remove(final String keyId);
	/**
	 * 查询
	 */
	String get(final String keyId);
}




@Service
public class RedisDaoImpl extends RedisGeneratorDao<String , String> implements RedisDao{

	@Override
	public boolean put(final String keyId, final String entity) {
		boolean result = redisTemplate.execute(new RedisCallback<Boolean>() {
			public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
				RedisSerializer<String> serializer = getRedisSerializer();
				byte[] key = serializer.serialize(keyId) ;
				byte[] value = serializer.serialize(entity) ;
				return connection.setNX(key, value);
			}
		});
		return result;
	}

	@Override
	public void remove(String key) {
		redisTemplate.delete(key) ;
	}

	@Override
	public String get(final String keyId) {
		String entity = redisTemplate.execute(new RedisCallback<String>() {  
			public String doInRedis(RedisConnection connection) throws DataAccessException {  
		        RedisSerializer<String> serializer = getRedisSerializer();  
		        byte[] key = serializer.serialize(keyId);  
		        byte[] value = connection.get(key);  
		        if (value == null) {  
		          return null;  
		        }  
		        return serializer.deserialize(value);  
		      }  
		    });  
		return entity ;  
	}

}



@Service
public class RedisDaoService {
	@Autowired
	private RedisDao redisDao ; 
	
	public boolean put(final String keyId , final Object entity){
		return redisDao.put(keyId ,  JSONObject.toJSONString(entity) ) ;
	}
	
	public <T> T get(final String keyId , Class<T> responseType){
		String jsonEntity = redisDao.get(keyId) ;
		if(Strings.isNullOrEmpty(jsonEntity)) return null ; 
		return JSONObject.parseObject(jsonEntity , responseType) ;
	}
	
	public String get(final String keyId){
		return redisDao.get(keyId)  ;
	}
	
	public void remove(final String keyId){
		redisDao.remove(keyId) ;
	}
	
}

import java.io.Serializable;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;

public abstract class RedisGeneratorDao<K extends Serializable, V extends Serializable> {
	@Autowired
	protected RedisTemplate<K , V> redisTemplate;

	public void setRedisTemplate(RedisTemplate<K , V> redisTemplate) {
		this.redisTemplate = redisTemplate;
	}

	protected RedisSerializer<String> getRedisSerializer() {
		return redisTemplate.getStringSerializer();
	}

}



@Aspect
public class ApplicationAspect {
	private static final Logger logger = Logger.getLogger(ApplicationAspect.class);
	private static final String APP_NAME = "PariskWeb" ;
	private static final String DB_SOURCE = ConfigPropertiesUtil.getContextProperty("dbsource") ;
	
	@Autowired
	private EbdAuthUserAuditLogService ebdAuthUserAuditLogService;
	@Autowired
	private RedisDaoService  redisService ;

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Around("execution(* cn.paic.rep.pare.controller..*.*(..)) && @annotation(sysLogger)")
	public Object doAround(ProceedingJoinPoint pjp , SysLogger sysLogger) throws Throwable{
		long startTimeMillis = System.currentTimeMillis() ;
		RequestAttributes ra = RequestContextHolder.getRequestAttributes() ;
		ServletRequestAttributes sra = (ServletRequestAttributes) ra ;
		HttpServletRequest request = sra.getRequest() ;
		String requestPath =  request.getServletPath() ;
		Map<String , String[]> inputParamMap = request.getParameterMap() ;
		TreeMultimap<String , String> requestSortedParam = TreeMultimap.create() ;
		for(Map.Entry<String, String[]> entry : inputParamMap.entrySet()){
			String[] values = entry.getValue() ;
			Arrays.sort(values) ;
			for(String value : values)
				requestSortedParam.put(entry.getKey() , StringUtils.toUTF8(value)) ;
		}
		String inputParams = "";
		for(Map.Entry<String , String> entry : requestSortedParam.entries()){
			inputParams += entry.getKey() + "=" + entry.getValue() + "&" ;
		}
		if(! Strings.isNullOrEmpty(inputParams)){
			requestPath += "?" + inputParams.substring(0 , inputParams.length() - 1) ;
		}
		
		/*redis模块*/
		RefreshNode freshNode = getRefreshNode(requestPath) ;
		Object result ;
		if(freshNode != null){//接口需要插缓存
			try{
				requestPath = String.format("%s-%s-%s" , APP_NAME , freshNode.isShare ? "" : DB_SOURCE , requestPath) ;
				JSONObject jsonEntity = redisService.get(requestPath , JSONObject.class);
				if(jsonEntity == null || toFresh(jsonEntity)){ //首次插入||需要刷新
					result = pjp.proceed() ;
					JSONObject toSaveJsonEntity = new JSONObject() ;
					Date toFreshBoundTime = DateUtils.addSecond(new Date() , freshNode.frushIntervalSeconds) ;
					toSaveJsonEntity.put("toFreshBoundTime" , DateUtils.DateToString(toFreshBoundTime , DateStyle.YYYY_MM_DD_HH_MM_SS));
					toSaveJsonEntity.put("data" , result) ;
					redisService.remove(requestPath) ;
					redisService.put(requestPath , toSaveJsonEntity) ;
				}else{//直接访问接口
					Signature signature = pjp.getSignature() ;
					Class returnType = ((MethodSignature) signature).getReturnType() ; //获得返回类型
					result = JSONObject.parseObject(jsonEntity.getString("data") , returnType) ;
				}
			}catch(Exception e){
				logger.error("call redis failed! ") ;
				result = pjp.proceed() ; 
			}
		} 
		else result = pjp.proceed() ;
		
		/*日志模块*/
		String userName = ShiroUtil.getUserName() ;
		if(! Strings.isNullOrEmpty(userName)){
			EbdAuthUserAuditLog userLog = new EbdAuthUserAuditLog() ;
			userLog.setUsername(userName) ;
			userLog.setActionDesc(sysLogger.description()) ;
			userLog.setLogtime(DateUtils.DateToString(new Date() , DateStyle.YYYY_MM_DD_HH_MM_SS)) ;
			userLog.setActionDescCn(sysLogger.description_cn()) ;
			userLog.setRequest_type(request.getMethod()) ;
			userLog.setRequest_uri(request.getRequestURI()) ;
			userLog.setRequest_para(requestPath) ;
			saveLog(userLog);
		}
		
		long endTimeMillis = System.currentTimeMillis();
		logger.info("User: " + userName + " , Action: " + sysLogger.description() + "\n"
				+ "Url: " + requestPath + "\n" 
				//+ "ResponseResults: " + JSONObject.toJSONString(result) + "\n" 
				+ "Cost:" + (endTimeMillis - startTimeMillis) + " ms " + "\n") ;
		return result;
	}
	
	private boolean toFresh(JSONObject jsonEntity){
		 Date toFreshBoundTime = DateUtils.StringToDate(jsonEntity.getString("toFreshBoundTime") , DateStyle.YYYY_MM_DD_HH_MM_SS) ;
		 return toFreshBoundTime.before(new Date()) ;
	} 
	
	private class RefreshNode{
		private Integer frushIntervalSeconds ; //更新间隔(秒)
		private Boolean isShare ; //Group与User环境是否共享缓存数据
		RefreshNode(Integer frushIntervalSeconds , Boolean isShare){
			this.frushIntervalSeconds = frushIntervalSeconds ; 
			this.isShare = isShare ; 
		}
	} 
	
	/*key=api url前缀  , value=刷新时间,单位秒*/
	private Map<String , RefreshNode> redisApi =  new ImmutableMap.Builder<String , RefreshNode>()
			 .put("/api/entprssignal/getDifferentDimensionSignal/4/1" , new RefreshNode(60 , Boolean.FALSE) )
			 .put("/api/companyBasic/queryEquityRelationship" , new RefreshNode(60*60 , Boolean.TRUE))
			 .build() ;
	
	private RefreshNode getRefreshNode(String requestPath){
		for(Map.Entry<String , RefreshNode> entry : redisApi.entrySet()){
			if(requestPath.contains(entry.getKey())) 
				return entry.getValue() ;  
		}
		return null ;
	}
	
	private void saveLog(EbdAuthUserAuditLog userLog) {
		ebdAuthUserAuditLogService.save(userLog);
	}

}








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值