SSM-Project-Day07 AOP【切面排序@Order(1)数字越小优先级越高】

一、添加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;
    }
}

演示:
在这里插入图片描述

3.2拷贝IPUtils.java和shrioUtils.java到common/util包下

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

SysLogDao

//    保存日志信息
    int insertObject(SysLog entity);

Mapping


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

SSM-Project-Day07 AOP【切面排序@Order(1)数字越小优先级越高】_第1张图片
SSM-Project-Day07 AOP【切面排序@Order(1)数字越小优先级越高】_第2张图片

你可能感兴趣的:(SSM+Shiro)