zoukankan      html  css  js  c++  java
  • AOP切面日志

    最近在公司做项目的时候,需要实现甲方的一个需求,修改操作的记录。
    XXX被谁修改为了XXX
    这个看起来很简单,例如修改只要得到参数的实体类Vo然后进行记录就行,但是在进行修改记录和新增记录的时候就会有问题了,首先update方法是可以得到主键ID的,因为是updateById,而新增是进行主键自增的,而删除如果是记录之前的数据就需要根据ID先去查然后再去删除。
    这三个其实对应的就是切面的三个顺序
    @After @Around @Before
    对于删除操作应该对应的是@Before需要在执行之间,先去完成查询,然后再由进程完成删除。
    对应修改则应该使用@Before。
    对应新增应该是@After操作,不然无法获得到Id。
    其实AOP的注解还有另外两种。

    • @Before: 前置通知, 在方法执行之前执行
    • @After: 后置通知, 在方法执行之后执行 。
    • @AfterRunning: 返回通知, 在方法返回结果之后执行
    • @AfterThrowing: 异常通知, 在方法抛出异常之后
    • @Around: 环绕通知, 围绕着方法执行

    简单说一下我是如何实现日志记录的。
    首先是需求:

     由于在权限方面我是用了shiro进行管理,所以我可以通过shiro的subject获得到我需求的“人名”

    String username = ((MemberEntity) SecurityUtils.getSubject().getPrincipal()).getName();
    

      

    然后我需要获得到发生切面的具体模块,这边可以有很多方法,例如通过方法判断
     
    MethodSignature signature = (MethodSignature) joinPoint.getSignature();
    Method method = signature.getMethod();
    

      

    我选择是的根据注解名字的不同来进行判断,然后通过具体的Key值得到我需要的value。
     
    if ("新增合同".equals(syslog.value())) {
    			//处理参数
    			Object[] args = joinPoint.getArgs();
    			//处理为Json字符串
    			String params = new Gson().toJson(args);
    			//处理字符串的[]
    			String replace = params.replace("[", "");
    			String s = replace.replace("]", "");
    			System.out.println(s);
    			//处理为Json对象
    			JSONObject jsonObject = JSON.parseObject(s);
    			//得到合同ID号
    			Object contractId = jsonObject.get("contractId");
    			//得到炼厂计划ID
    			Object filiale_plan_id = jsonObject.get("filialePlanId");
    			Integer ID = Integer.valueOf(String.valueOf(filiale_plan_id));
    			//得到合同号
    			Object contracts = jsonObject.get("contracts");
    			//得到合同价格
    			Object agreement_price = jsonObject.get("agreementPrice");
    			//得到资源大体流向
    			Object resource_stream = jsonObject.get("resourceStream");
    			log.append(username).append("新增了合同,合同号为:").append(contracts).append(",合同价格为:").append(agreement_price);
    			sysLog.setParams(log.toString());
    			sysLog.setFilialePlanId(ID);
    		}
    

      

    这样写的缺点就是无法复用,只能针对某一个去写,所以这个需求我一共写了388行代码.....很笨重,后续是肯定要修改这个方法的。

    AOP只是一个概念并没有设定具体语言的实现,它能克服那些只有单继承特性语言的缺点。实现AOP的技术主要分为两类:一类是采用动态代理技术利用截取消息的方式,对消息进行装饰以取代原有对象行为的执行。另一类是采用静态织入的方式,引入特定语法创建切面,从而使编译器可以在编译期间织入相关的切面代码。
     
    切面的使用:
    1.切入点:对哪些方法进行拦截,拦截后怎样处理。应用通知进行增强的目标方法
    2.切面:也就是具体的写代码的地方(例如日志模块)。是切入点和通知的结合
    3.连接点:连接点是程序执行过程中明确的点,一般是类中方法的调用。连接点是程序在运行过程中能够插入切面的地点,比如方法调用、异常抛出、字段修改等。连接点就是可以应用通知进行增强的方法

     案例代码:

    @Aspect
    @Component
    public class SysLogAspect {
    
    	@Pointcut("@annotation(io.ref.common.annotation.SysLog)")
    	public void logPointCut() { 
    		
    	}
    
    	@Before("logPointCut()")
    	public Object before(JoinPoint point) throws Throwable {
    		long beginTime = System.currentTimeMillis();
    		//执行方法
    		Object result = point.getTarget();
    		//执行时长(毫秒)
    		long time = System.currentTimeMillis() - beginTime;
    		//保存日志
    		saveSysLog(point, time);
    
    		return result;
    	}
    	private void saveSysLog(JoinPoint joinPoint, long time) {
    		MethodSignature signature = (MethodSignature) joinPoint.getSignature();
    		Method method = signature.getMethod();
    
    		SysLogEntity sysLog = new SysLogEntity();
    		SysLog syslog = method.getAnnotation(SysLog.class);
    		if(syslog != null){
    			//注解上的描述
    			sysLog.setOperation(syslog.value());
    		}
    
    		//获取request
    		HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
    		//设置IP地址
    		sysLog.setIp(IPUtils.getIpAddr(request));
    
    		//用户名
    		String username = ((MemberEntity) SecurityUtils.getSubject().getPrincipal()).getName();
    		sysLog.setName(username);
    

      

  • 相关阅读:
    Open source cryptocurrency exchange
    Salted Password Hashing
    95. Unique Binary Search Trees II
    714. Best Time to Buy and Sell Stock with Transaction Fee
    680. Valid Palindrome II
    Java compiler level does not match the version of the installed Java project facet.
    eclipse自动编译
    Exception in thread "main" java.lang.StackOverflowError(栈溢出)
    博客背景美化——动态雪花飘落
    java九九乘法表
  • 原文地址:https://www.cnblogs.com/SmartCat994/p/13023268.html
Copyright © 2011-2022 走看看