欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

使用spring通过aop获取方法参数和参数值

程序员文章站 2022-03-02 11:30:30
目录spring通过aop获取方法参数和参数值自定义注解package com.xiaolc.aspect; import java.lang.annotation.*; /** * @author...

spring通过aop获取方法参数和参数值

自定义注解

package com.xiaolc.aspect;  
import java.lang.annotation.*; 
/**
 * @author lc
 * @date 2019/9/10
 */
@documented
@target({elementtype.type, elementtype.method})
@retention(retentionpolicy.runtime)
public @interface licheng {
}

切面

package com.xiaolc.aspect; 
import org.aspectj.lang.proceedingjoinpoint;
import org.aspectj.lang.annotation.around;
import org.aspectj.lang.annotation.aspect;
import org.springframework.core.defaultparameternamediscoverer;
import org.springframework.core.parameternamediscoverer;
import org.springframework.stereotype.component;
 
import java.lang.reflect.method;
import java.util.hashmap;
import java.util.map;
 
/**
 * 获取方法上的注解值
 */
@component
@aspect
public class auditannotationaspect {
 
    @around("@annotation(licheng))")
    private static map getfieldsname(proceedingjoinpoint joinpoint,licheng licheng) throws classnotfoundexception, nosuchmethodexception {
        string classtype = joinpoint.gettarget().getclass().getname();
        string methodname = joinpoint.getsignature().getname();
        // 参数值
        object[] args = joinpoint.getargs();
        class<?>[] classes = new class[args.length];
        for (int k = 0; k < args.length; k++) {
            if (!args[k].getclass().isprimitive()) {
                // 获取的是封装类型而不是基础类型
                string result = args[k].getclass().getname();
                class s = map.get(result);
                classes[k] = s == null ? args[k].getclass() : s;
            }
        }
        parameternamediscoverer pnd = new defaultparameternamediscoverer();
        // 获取指定的方法,第二个参数可以不传,但是为了防止有重载的现象,还是需要传入参数的类型
        method method = class.forname(classtype).getmethod(methodname, classes);
        // 参数名
        string[] parameternames = pnd.getparameternames(method);
        // 通过map封装参数和参数值
        hashmap<string, object> parammap = new hashmap();
        for (int i = 0; i < parameternames.length; i++) {
            parammap.put(parameternames[i], args[i]);
            system.out.println("参数名:"+parameternames[i]+"\n参数值"+args[i]);
        }
        return parammap;
    }
    private static hashmap<string, class> map = new hashmap<string, class>() {
        {
            put("java.lang.integer", int.class);
            put("java.lang.double", double.class);
            put("java.lang.float", float.class);
            put("java.lang.long", long.class);
            put("java.lang.short", short.class);
            put("java.lang.boolean", boolean.class);
            put("java.lang.char", char.class);
        }
    };
}

aop切面 注解、参数获取

在工作中会经常使用aop,这里将aop使用基本方法,获取在切点中使用的获取参数、注解做一个样例。

1、定义需要切面的注解

@target(elementtype.method)
@retention(retentionpolicy.runtime)
@documented
public @interface anndemo {
    string value();
    boolean isaop() default true;
}

2、在需要进行切面的方法标注注解

@restcontroller
@requestmapping("/order")
public class ordercontroller {
    @autowired
    private orderservice orderservice;
    @requestmapping("/all")
    @anndemo(value = "all",isaop = false)
    public list<tborder> findall() {
        list<tborder> list = orderservice.getorderlist();
        return list;
    }
    @requestmapping("/page")
    @anndemo(value = "page")
    public list<tborder> findpage(@requestparam("username") string username) {
        list<tborder> listpage = orderservice.getorderslistpage();
        return listpage;
    }
}

3、定义切面

在切面中获取切点注解,方法,参数的获取

@aspect
@component
public class aspectdemo {
    @pointcut(value = "execution(* com.yin.freemakeradd.controller..*(..))")
    public void excetionmethod() {}
    @pointcut(value = "execution(* com.yin.freemakeradd.controller..*(..)) && @annotation(anndemo)")
    public void excetionnote() { }
    @before("excetionmethod()")
    public void testbefore(joinpoint joinpoint) {
        system.out.println("----------------------------前置通知---");
        object[] args = joinpoint.getargs();
        for (object arg : args) {
            system.out.println(arg);
        }
    }
    @around(value = "execution(* com.yin.freemakeradd.controller..*(..)) && @annotation(anndemo)")
    public object  testbeforenote(proceedingjoinpoint joinpoint) throws throwable {
        //用的最多通知的签名
        signature signature = joinpoint.getsignature();
        methodsignature msg=(methodsignature) signature;
        object target = joinpoint.gettarget();
        //获取注解标注的方法
        method method = target.getclass().getmethod(msg.getname(), msg.getparametertypes());
        //通过方法获取注解
        anndemo annotation = method.getannotation(anndemo.class);
        object proceed;
        //获取参数
        object[] args = joinpoint.getargs();
        system.out.println(annotation.value());
        system.out.println(annotation.isaop());
        for (object arg : args) {
            system.out.println(arg);
        }
        if (objects.isnull(annotation) || !annotation.isaop()) {
            system.out.println("无需处理");
            proceed = joinpoint.proceed();
        }else {
            system.out.println("进入aop判断");
            proceed = joinpoint.proceed();
            if(proceed instanceof list){
                list proceedlst = (list) proceed;
                if(!collectionutils.isempty(proceedlst)){
                    tborder tborder = new tborder();
                    tborder.setpaymenttype("fffffffffffffffffff");
                    arraylist<tborder> tborderlst = new arraylist<>();
                    tborderlst.add(tborder);
                    return tborderlst;
                }
            }
            system.out.println(proceed);
        }
        return proceed;
    }
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。