import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @Inherited允許子類繼承父類中的註解
* @Documented註解表明製作javadoc時,
* 是否將註解信息加入文檔。如果註解在聲明時使用了@Documented,
* 則在製作javadoc時註解信息會加入javadoc。
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
String value() default "";
}
@Target (目標,靶子...)
public enum ElementType {
/** 類、接口(包括註釋類型)或枚舉聲明 */
TYPE,
/** 字段聲明(包括枚舉常量) */
FIELD,
/** 方法聲明 */
METHOD,
/** 正式的參數聲明 */
PARAMETER,
/** 構造函數聲明 */
CONSTRUCTOR,
/** 局部變量聲明 */
LOCAL_VARIABLE,
/** 註釋類型聲明 */
ANNOTATION_TYPE,
/** 程序包聲明*/
PACKAGE,
/**
* 類型參數聲明
*
* @since 1.8
*/
TYPE_PARAMETER,
/**
* 使用類型
*
* @since 1.8
*/
TYPE_USE
}
@Retention
表示需要再什麼級別保存該註解信息,可選的RetentionPolicy參數包括:
SOURCE:註解將被編譯器丟棄。
CLASS:註解再class文件中可用,但會被VM丟棄。
RUNTIME:VM將在運行期也保留註解,因此可以通過反射機制讀取註解的信息。
利用AOP對方法級別的註解做相應的操作
package com.fun.utils;
import com.fun.client.domain.MemUserInfo;
import com.fun.client.domain.OperationLog;
import com.fun.client.service.MemUserInfoService;
import com.fun.client.service.OperationLogService;
import com.fun.framework.support.BusinessException;
import com.fun.framework.utils.RequestUtils;
import org.apache.commons.lang3.math.NumberUtils;
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.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;
@Aspect
@Component
public class LogAspect {
/* @Autowired
private SysLogDao sysLogDao;*/
@Autowired
private MemUserInfoService memUserInfoService;
@Autowired
private OperationLogService operationLogService;
@Pointcut("@annotation(com.fun.utils.Log)")
public void pointcut() { }
@Around("pointcut()")
public Object around(ProceedingJoinPoint point) throws Exception {
Object result = null;
long beginTime = System.currentTimeMillis();
try {
// 執行方法
result = point.proceed();
} catch (Throwable e) {
e.printStackTrace();
}
// 執行時長(毫秒)
// long time = System.currentTimeMillis() - beginTime;
// 保存日誌
saveLog(point);
return result;
}
private void saveLog(ProceedingJoinPoint joinPoint) throws Exception {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
OperationLog operationLog = new OperationLog ();
Log logAnnotation = method.getAnnotation(Log.class);
if (logAnnotation != null) {
// 註解上的描述
operationLog.setContent(logAnnotation.value());
}
//獲取當前用戶ID(Security框架)
int userId = NumberUtils.toInt(SecurityContextHolder.getContext().getAuthentication().getName());
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
String ip = null ;
//String ipAddress;
try {
if (userId >= 1) {
//獲取當前用戶登錄真實IP(RequestUtils獲取當前登陸者ip等信息工具類下章有寫)
ip = RequestUtils.getIp(request);
//解析IP爲地址
// ipAddress = RequestUtils.getIpAddress(ip);
//登錄瀏覽器類別
// String agent = RequestUtils.getAgent(request);
// this.memService.addLoginLog(userId, ip, ipAddress, agent);
}
} catch (Exception ex2) {
}
//插入數據到數據庫
MemUserInfo memUserInfo = memUserInfoService.selectById(userId);
operationLog.setMemberId(userId);
operationLog.setMemberName(memUserInfo.getLoginName());
operationLog.setOperationIp(ip);
operationLog.setMemberRemark(memUserInfo.getRemark());
operationLogService.insert(userId,operationLog);
}
}