1、主要實現用戶在進行某項操作時,多數據庫的更新、插入和刪除詳細信息。記錄操作時的請求信息。
2、在進入Controller時,生成一個事物ID,在這個Controller中進行的所有DAO操作都綁定該事物ID。并進行記錄日志信息。
package com.centralsoft.filter;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
import java.util.regex.Pattern;
import net.sf.json.JSONObject;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import com.centralsoft.cache.CacheService;
import com.centralsoft.cache.annotations.Cache;
import com.centralsoft.cache.entity.MemCacheKey;
import com.centralsoft.entity.SysLogDetail;
import com.centralsoft.manager.pub.ThreadBean;
import com.centralsoft.manager.pub.ThreadId;
import com.centralsoft.pub.dao.SysLogDAO;
import com.centralsoft.webservice.pub.DateSHA;
/**
* DAO層AOP攔截器,實現記錄用戶操作過的所有方法和參數,并實現DAO層緩存
*
* @author Administrator
*
*/
@Aspect
@Component
public class AspectAutoDAOBean {
@Autowired
@Qualifier("CacheService")
private CacheService memcache;
@Autowired
@Qualifier("SysLogDAO")
private SysLogDAO SysLogDAO;
@Around("execution(* com.centralsoft.*.dao.Zr*DAO.*(..))")
public Object before(ProceedingJoinPoint joinPoint) throws Throwable {
// 獲取請求事務ID信息
ThreadId threadId = new ThreadBean().getThreadId();
// 調用方法名稱
String methodName = joinPoint.getSignature().getName();
// 調用參數
Object[] args = joinPoint.getArgs();
Object object = null;
// 數據庫更新操作日志
if (Pattern.matches("(save|insert|add|delete|remove|del|update)[\\S]*",
methodName)) {
if (threadId != null && threadId.getTransactionalId() != null) {
// 獲取執行請求事務ID
String transactionalId = threadId.getTransactionalId();
// 獲取執行請求用戶ID
String userId = threadId.getUserId();
SysLogDetail sysLogDetail = new SysLogDetail();
sysLogDetail.setXh(transactionalId);
sysLogDetail.setUserId(userId);
sysLogDetail.setMethod(methodName);
JSONObject msg = new JSONObject();
// 處理參數
for (Object temp : args) {
// 獲取參數類型,不同參數類型數據處理不一樣
Class<? extends Object> paramClazz = temp.getClass();
String classType = paramClazz.getName();
if (classType.equals("java.lang.String")) {
msg.put("key", temp);
} else if (classType.equals("java.util.HashMap")) {
msg.putAll((HashMap<?, ?>) temp);
} else if (classType.startsWith("com.")) {
try {
Field[] f = paramClazz.getDeclaredFields();
for (Field field : f) {
String fieldName = field.getName();
field.setAccessible(true);
msg.put(fieldName, field.get(temp));
}
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}
}
sysLogDetail.setMsg(msg.toString());
// 記錄DAO數據庫操作日志
SysLogDAO.insertSysLogDetail(sysLogDetail);
}
// 執行數據庫操作
object = joinPoint.proceed();
// 數據庫查詢緩存
} else if (Pattern.matches("(query|load|get|select|read)[\\S]*",
methodName)) {
// DAO層緩存注解
MemCacheKey cacheKey = new MemCacheKey();
// 獲取cache注解屬性
Cache cache = null;
// 獲取請求方法
Class<?> cls = joinPoint.getTarget().getClass();
// 獲取class中的所有方法
Method[] methods = cls.getMethods();
for (Method m : methods) {
// 獲取執行方法前的注解信息。
if (m.getName().equals(methodName)) {
cache = m.getAnnotation(Cache.class);
break;
}
}
if (cache != null) {
// 獲取memcacheKey,并進行MD5加密
cacheKey = memcacheKey(cache, args);
// 判斷緩存服務器是否存在該可以值
if (memcache.exist(cacheKey.getMemcacheKey())) {
object = memcache.get(cacheKey.getMemcacheKey());
} else {
// 執行數據庫操作
object = joinPoint.proceed();
// 將數據存放進緩存
if (cacheKey.getMemcacheKey() != null) {
memcache.put(cacheKey.getMemcacheKey(),
object == null ? "" : object, new Date(cacheKey
.getTime()));
}
}
} else {
// 執行數據庫操作
object = joinPoint.proceed();
}
} else {
// 執行數據庫操作
object = joinPoint.proceed();
}
return object;
}
/**
* 獲取根據注解中的key獲取memcache的含參數key值
*
* @param cache
* @param parameterObject
* @return
* @author fei.zhao 2011-10-10
*/
@SuppressWarnings("unchecked")
private static MemCacheKey memcacheKey(Cache cache, Object[] args) {
MemCacheKey tempKey = new MemCacheKey();
String key = "";
boolean flag = true;
StringBuilder keyBuilder = new StringBuilder(32);
// 獲取注解中的key值
String cacheKey = cache.key();
Object[] cacheArgs = cacheKey.split("\\.");
// 設置請求參數在args[]中的序號
// key參數進行循環遍歷
for (Object s : cacheArgs) {
// 判斷是否是格式$,$...
if (s.toString().startsWith("$")) {
// 獲取參數名稱
String type = s.toString().substring(1);
// 獲取參數值
Object temp = args[0];
// 獲取參數類型,不同參數類型數據處理不一樣
Class<? extends Object> paramClazz = temp.getClass();
String classType = paramClazz.getName();
if (classType.equals("java.lang.String")) {
keyBuilder.append(temp);
} else if (classType.equals("java.util.HashMap")) {
keyBuilder.append(((HashMap) temp).get(type));
} else if (classType.startsWith("com.")) {
try {
Field f = paramClazz.getDeclaredField(type);// 實體中字段
f.setAccessible(true);// 允許訪問私有字段
keyBuilder.append(f.get(temp));
} catch (SecurityException e) {
flag = false;
e.printStackTrace();
} catch (NoSuchFieldException e) {
flag = false;
e.printStackTrace();
} catch (IllegalArgumentException e) {
flag = false;
e.printStackTrace();
} catch (IllegalAccessException e) {
flag = false;
e.printStackTrace();
}
}
} else {
keyBuilder.append(s);
}
// 每個參數后面添加 “.”號分隔
keyBuilder.append(".");
}
if (args.length == 3) {
keyBuilder.append(args[1] + ".").append(args[2]);
}
if (flag == true) {
key = keyBuilder.toString();
tempKey.setMemcacheKey(DateSHA.shaEncrypt(key));
tempKey.setTime(cache.time());
}
return tempKey;
}
}