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