一、添加pom依赖
org.springframework
spring-context
4.3.9.RELEASE
org.aspectj
aspectjrt
1.8.9
org.aspectj
aspectjweaver
1.8.9
二、在dispatcher-servlet.xml中添加aop注解配置
会自动扫描aspect的注解
三、在common文件夹下新建aspect包、新建SysLogAspect类
3.1
/**
* @author : zhenzhen
* @date : 2019/4/3 20:47
* Aspect用来描述此类是一个日志横切面对象
* 完成日志功能:抓取用户操作的内容写入日志
*/
@Aspect
@Service
public class SysLogAspect {
// @Around:描述方法为一个环绕通知
// 围绕bean添加日志抓取操作
// 环绕通知:目标方法执行之前和之后都可以执行
// pjp表示一个一个连接点对象,封装了一个具体的业务方法
// 环绕通知内部的bean表达式为你一个切入点表达式
// bean对象名字要一样 首字母小写
@Around("bean(sysRoleServiceImpl)")
public Object aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable{
long startTime = System.currentTimeMillis();
// 执行目标方法
Object result = joinPoint.proceed(); //不要处理异常,直接抛出
long endTime = System.currentTimeMillis();
// 获取类
Class> targetCls = joinPoint.getTarget().getClass();//.getTarget()获取目标对象 .getClass()获取
Signature s = joinPoint.getSignature();//拿到方法签名
String method = s.getName();//获得到方法名
System.out.println(targetCls+"."+method+"->totalTime:"+(endTime-startTime));
return result;
}
}
private static Logger logger = LoggerFactory.getLogger(IPUtils.class);
/**
* 获取IP地址
* 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址
* 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址
*/
public static String getIpAddr() {
HttpServletRequest request=
((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String ip = null;
try {
ip = request.getHeader("x-forwarded-for");
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (StringUtils.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
} catch (Exception e) {
logger.error("IPUtils ERROR ", e);
}
// //使用代理,则获取第一个IP地址
// if(StringUtils.isEmpty(ip) && ip.length() > 15) {
// if(ip.indexOf(",") > 0) {
// ip = ip.substring(0, ip.indexOf(","));
// }
// }
return ip;
}
public static SysUser getPrincipal(){
return (SysUser)SecurityUtils
.getSubject().getPrincipal();
}
// 获取日志信息写入数据库方法
private void SaveObject(ProceedingJoinPoint joinPoint,long time){
// 获取日志信息
// 获取类 、方法签名 、 方法名 、方法参数
Class> targetCls = joinPoint.getTarget().getClass();//.getTarget()获取目标对象 .getClass()获取
Signature s = joinPoint.getSignature();//拿到方法签名
String methodName = s.getName();//获得到方法名
Object[] params = joinPoint.getArgs();//获取方法参数 是数组
System.out.println(targetCls+"."+methodName+"->totalTime:"+time);
// 用户名:登陆成功后 shiro访问就会获取到身份 强转类型为SysUser
// SysUser user=(SysUser)SecurityUtils.getSubject().getPrincipal();
// 封装日志信息
SysLog log = new SysLog();
log.setMethod(methodName);
log.setIp(IPUtils.getIpAddr());
// log.setOperation();
log.setParams(Arrays.toString(params));//
log.setUsername(ShiroUtils.getPrincipal().getUsername());
// 保存日志信息
// SysLogDao.insertObject(log);
}
// 保存日志信息
int insertObject(SysLog entity);
insert into sys_logs
(username,operation,method,params,time,ip,createdTime)
values
(#{username},#{operation},#{method},#{params},#{time},#{ip},#{createdTime})
aspect中关联SysLogDao
//关联SysLogDao
@Autowired
private SysLogDao sysLogDao;
// 保存日志信息
sysLogDao.insertObject(log);
/**
* 监控切面
* @author ta
*/
@Order(3)
@Aspect
@Service
public class SysMonitorAspect {
@Pointcut("bean(*ServiceImpl)")
public void pointCut(){}
/**
* 前置通知(目标方法执行之前)
*/
@Before("pointCut()")
public void beforeMethod(){//例如开启事务
System.out.println("beforeMethod");
}
/**
* 返回通知(正常结束以后,后置通知@After之后执行)
*/
@AfterReturning("pointCut()")
public void returnMethod(){//例如提交事务
System.out.println("returnMethod");
}
/**
* 异常通知(出现异常之后@After之后执行)
*/
@AfterThrowing("pointCut()")
public void throwMethod(){//回滚事务
System.out.println("throwMethod");
}
/**后置通知:目标方法之后执行*/
@After("pointCut()")
public void afterMethod(){//释放资源
System.out.println("beforeMethod");
}
}