spring AOP + 自定义注解 实现

  • Post author:
  • Post category:其他




1.首先在spring mvc 的配置文件中确定扫描包

<context:component-scan base-package=“com.sun.controller,com.sun.annotation” />



2.其次配置aop aspectj 自动注解识别

<aop:aspectj-autoproxy proxy-target-class=“true”/>



3.自定义注解类

package com.sun.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)//定义了该Annotation被保留的时间长短(1.SOURCE:在源文件中有效(即源文件保留)2.CLASS:在class文件中有效(即class保留)3.RUNTIME:在运行时有效(即运行时保留))
@Target({ElementType.FIELD,ElementType.METHOD,ElementType.TYPE})//Annotation所修饰的对象范围 属性,方法,类等
//@Documented//描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化
//@Inherited //元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类
public @interface First {
    String value() default "";
    int num();
}



4.自定义的Aspect切面类

package com.sun.annotation;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Component
public class AspectJ {

    public AspectJ(){
        System.out.println("AspectJ---加载");
    }
//    @Pointcut("execution(public * com.sun.controller.*.*(..))")//定义作用的方法范围
//    @Pointcut("@annotation(com.sun.annotation.First)")//定义作用的注解
    @Pointcut("execution(@com.sun.annotation.First public * com.sun.controller.*.*(..))")//定义作用的注解+方法范围
    public void t(){}

    @Before("t()")
    public void t1(JoinPoint joinPoint){
        System.out.println("t1");
        Object[] args = joinPoint.getArgs();//获得切面方法当中的参数
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();//获得切面当中方法签名
        Method method = signature.getMethod();//获得签名方法
        First first = signature.getMethod().getAnnotation(First.class);//获得方法上的注解
        if(first.num()==1){
            System.out.println("允许访问");
        }else{
            throw new RuntimeException("false");
        }
		//List<Long> ids = resolveVar(first.value(), args, signature);


    }

    @After("t()")
    public void t2(JoinPoint joinPoint){
        System.out.println("t2");
    }

    @AfterReturning("t()")
    public void t3(JoinPoint joinPoint){
        System.out.println("t3");
    }

    @AfterThrowing("t()")
    public void t4(JoinPoint joinPoint){
        System.out.println("t4");
    }

	/**
     * 解析ids
     * @param var
     * @param args
     * @param signature
     * @return
     */
    private List<Long> resolveVar(String var, Object[] args, MethodSignature signature) {
        if(StringUtils.isEmpty(var)) {
            return new ArrayList<>();
        }
        // 先通过 . 分割
        String[] varSplit = StringUtils.split(var, '.');//如注解值为user.id
        // 获取方法入参名称列表
        String[] parameterNames = signature.getParameterNames();//如入参User user,Role role
        // 找到入参对应的index
        int index = 0;
        for(int i = 0; i < parameterNames.length; i++) {
            if(parameterNames[i].equals(varSplit[0])) {//varSplit[0]=user,parameterNames[0]=user
                index = i;
                break;
            }
        }
        Object arg = args[index];
        Class clazz = signature.getParameterTypes()[index];

        for(int i = 1; i < varSplit.length; i++) {
            // 查找字段
            Field field = ReflectionUtils.findField(clazz, varSplit[i]);//从User中找到属性为id的field
            if(field == null) {
                throw new RuntimeException("id变量不存在, var:" + var);
            }
            field.setAccessible(true);
            try {
                arg = field.get(arg);
                clazz = field.getType();
            } catch (IllegalAccessException e) {
                throw new RuntimeException("id变量不存在, var:" + var, e);
            }
        }
        return arg == null ? new ArrayList<>() : getIds(arg);
    }

    private List<Long> getIds(Object arg) {
        if(arg instanceof Long) {
            return Collections.singletonList((Long) arg);
        } else if(arg instanceof List) {
            return (List<Long>) arg;
        } else if(arg instanceof Long[]) {
            return Arrays.asList((Long[])arg);
        } else {
            throw new RuntimeException("只支持配置Long或者List<Long>类型团队id, 解析后的类型:" + arg.getClass().toGenericString());
        }
    }

}



5.调用的方法

	@First(value = "s",num = 1)
    @RequestMapping("/echarts")
    public String echarts(){
        System.out.println("****chartsTest***");
        return "chartsTest";
    }
    @First(value = "s",num = 2)
    @RequestMapping("/getPeoplelrData")
    @ResponseBody
    public Object getPeoplelrList(){
        System.out.println("*******");
        List<Peoplelr> r = peoplelrService.getPeoplelrList();
        return r;
    }

	

调用echarts 允许访问,调用getPeoplelrList 抛出异常



版权声明:本文为qq_25210899原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。