springboot---aop切片編程


1.介紹

  面向切面編程,關注點代碼與業務代碼分離,就是給指定方法執行前執行后。。插入重復代碼

  關注點:重復代碼

  切面:被切面的類

  切入點:執行目標對象方法,動態植入切片代碼

2.部署步驟

  2.1:添加依賴

<!-- spring aop支持-->  
        <dependency>
              <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-aop</artifactId>

  2.2 aop切片配置

package com.ty.tyzxtj.aop;

import java.util.HashMap;
import java.util.Map;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javassist.ClassClassPath;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.Modifier;
import javassist.NotFoundException;
import javassist.bytecode.CodeAttribute;
import javassist.bytecode.LocalVariableAttribute;
import javassist.bytecode.MethodInfo;

/**
 * 調用接口的切面類
 * @author wangjiping
 *
 */
@Aspect
@Component
public class WebLogAspect  {
    private Logger logger = null; 
    /**
     * 定義一個切面
     */
    @Pointcut("execution(* com.ty.tyzxtj.controller.*.*(..))")
    public void webLog(){
        
    }
    @Before("webLog()")  
    public void doBefore(JoinPoint joinPoint) throws Throwable {  
        // 接收到請求,記錄請求內容  
        Class<?> target = joinPoint.getTarget().getClass();//目標類
        logger = LoggerFactory.getLogger(target);//對應日志成員
        String clazzName = target.getName();//類名
        Object[] args = joinPoint.getArgs();//參數
        String methodName = joinPoint.getSignature().getName();//方法名
        Map<String,Object> nameAndArgs = getFieldsName(this.getClass(), clazzName, methodName, args);//獲取被切參數名稱及參數值
        logger.info("["+clazzName+"]["+methodName+"]["+nameAndArgs.toString()+"]");
        //獲取參數名稱和值
    }  
  
    @AfterReturning(returning = "ret", pointcut = "webLog()")  
    public void doAfterReturning(Object ret) throws Throwable {  
        // 處理完請求,返回內容  
        logger.info("response : " + ret);
    }  
    
    /**
     * 通過反射機制 獲取被切參數名以及參數值
     *
     * @param cls
     * @param clazzName
     * @param methodName
     * @param args
     * @return
     * @throws NotFoundException
     */
    private Map<String, Object> getFieldsName(Class<?> cls, String clazzName, String methodName, Object[] args) throws NotFoundException {
        Map<String, Object> map = new HashMap<String, Object>();
        ClassPool pool = ClassPool.getDefault();
        //ClassClassPath classPath = new ClassClassPath(this.getClass());
        ClassClassPath classPath = new ClassClassPath(cls);
        pool.insertClassPath(classPath);

        CtClass cc = pool.get(clazzName);
        CtMethod cm = cc.getDeclaredMethod(methodName);
        MethodInfo methodInfo = cm.getMethodInfo();
        CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
        LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag);
        if (attr == null) {
        }
        int pos = Modifier.isStatic(cm.getModifiers()) ? 0 : 1;
        for (int i = 0; i < cm.getParameterTypes().length; i++) {
            map.put(attr.variableName(i + pos), args[i]);//paramNames即參數名
        }
        return map;
    }
}

 

3.注意事項


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM