基于注解的AOP实现

15 篇文章 0 订阅
8 篇文章 0 订阅

  在web项目中有很多的AOP是基于路径来拦截的,但是有些情况下项目的API路径是多种多样的,而且需要被拦截做AOP的API也是杂七乱八的,那这种情况下,我们基于包路径的AOP的能力就会觉着很无力。曾经我使用的是黑白名单的功能支持。但是后来发现这种方案代价也挺高的。下面我简单介绍下基于配置注解的AOP拦截,这中实现方案,对我上文讲述的问题的支持能力个人感觉真是太好了。
首先创建一个注解

package org.demo.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD })
public @interface DemoPermission {
    String[] demo() default {};

}

基于当前注解实现AOP

package org.demo;

import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.Map;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.demo.annotations.DemoPermission;
import org.demo.controller.DemoFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class CopyOfPermissionAspect {

    @Autowired(required = false)
    DemoFactory demoFactory;

    @Before("@annotation(org.demo.annotations.DemoPermission)")
    public void before(JoinPoint caller) {
        Map<String, Object> functionParamValueMap = getFunctionParamValueMap(caller);
        DemoPermission annotation = getAnnotation(caller, DemoPermission.class);
        System.out.println("before-->" + annotation);
    }

    @After("@annotation(org.demo.annotations.DemoPermission)")
    public void after(JoinPoint caller) {
        DemoPermission annotation = getAnnotation(caller, DemoPermission.class);
        System.out.println("after-->" + annotation);

    }

    @Around("@annotation(org.demo.annotations.DemoPermission)")
    public Object around(ProceedingJoinPoint pjp) {
        DemoPermission annotation = getAnnotation(pjp, DemoPermission.class);
        System.out.println("around-->" + annotation);
        Object proceed = null;
        try {
            proceed = pjp.proceed();
        } catch (Throwable e) {
        }
        return proceed;
    }


    private <T extends Annotation> T getAnnotation(JoinPoint caller,
            Class<T> annotationClass) {
        if (caller.getSignature() instanceof MethodSignature) {
            MethodSignature methodSignature = (MethodSignature) caller
                    .getSignature();
            return methodSignature.getMethod().getAnnotation(annotationClass);
        }
        return null;
    }

    private Map<String, Object> getFunctionParamValueMap(JoinPoint caller) {
        Map<String, Object> result = new HashMap<>();
        if (caller.getSignature() instanceof MethodSignature) {
            Object[] paramsValues = caller.getArgs();
            MethodSignature methodSignature = (MethodSignature) caller
                    .getSignature();
            String[] paramNames = methodSignature.getParameterNames();
            for (int i = 0, len = paramNames.length; i < len; i++) {
                String paramName = paramNames[i];
                Object paramValue = paramsValues[i];
                result.put(paramName, paramValue);
            }
        }
        return result;
    }
}

然后使用注解测试下功能

package org.demo.controller;

import org.demo.annotations.DemoAspect;

import org.demo.annotations.DemoPermission;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DemoController {

    @DemoPermission
    @RequestMapping("/demo")
    public String demo(String name) {
        System.out.println("demo--->" + name);
        return "demo";
    }

}

  这个是一个最简单是实现demo,在此基础上我们可以做更多的扩展和支持。详细的扩展代码就不在此一一列出了。
  更多代码请访问GitHub

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值