<?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);
}
}