Spring MethodInterceptor 实现(注解+SpEL表达式)源码级AOP功能

前言

源码级:实现代码是通过Spring Security 源码仿照的。
网上常见的方式 Spring框架提供的:DefaultPointcutAdvisor + AspectJExpressionPointcut或AnnotationMatchingPointcut
本文采用的是全自定义的方式。

定义注解

常规固定写法

@Target({METHOD, TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface PreAspect {

    String value();
}

Pointcut 切入点

常用的切入点:AspectJExpressionPointcut或AnnotationMatchingPointcut

StaticMethodMatcherPointcut

静态方法切入点匹配器

    class MethodAspectMetadataSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {
        /**
         * 此方法项目启动的时候遍历项目全部方法,需要拦截的方法返回true。
         * attributeSource 自定义功能类:查询方法是否被 @PreAspect 注解修饰
         */  
        public boolean matches(Method m, Class targetClass) {
            Collection<ConfigAttribute> attributes = attributeSource.getAttributes(m, targetClass);
            return attributes != null && !attributes.isEmpty();
        }
    }

Pointcut Advisor

继承AbstractPointcutAdvisor 自定义实现

public class MethodAspectMetadataSourceAdvisor extends AbstractPointcutAdvisor {

    private transient MethodAspectMetadataSource attributeSource;
    private transient MethodInterceptor interceptor;
    private final Pointcut pointcut = new MethodAspectMetadataSourcePointcut();

    public MethodAspectMetadataSourceAdvisor(MethodInterceptor interceptor, MethodAspectMetadataSource attributeSource) {
        this.interceptor = interceptor;
        this.attributeSource = attributeSource;
    }

    @Override
    public Pointcut getPointcut() {
        return pointcut;
    }

    @Override
    public Advice getAdvice() {
        return interceptor;
    }

    // ~ 内部类
    // =================================================================================================================

    class MethodAspectMetadataSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {
        public boolean matches(Method m, Class targetClass) {
            Collection<ConfigAttribute> attributes = attributeSource.getAttributes(m, targetClass);
            return attributes != null && !attributes.isEmpty();
        }
    }
}

扩展

  1. AspectJExpressionPointcutAdvisor
    内部已经 new AspectJExpressionPointcut();
    在这里插入图片描述

MethodInterceptor

public class MethodAspectInterceptor extends AbstractAspectInterceptor implements
        MethodInterceptor {

    private MethodAspectMetadataSource aspectMetadataSource;

    public void setAspectMetadataSource(MethodAspectMetadataSource newSource) {
        this.aspectMetadataSource = newSource;
    }

    @Override
    public Class<?> getSecureObjectClass() {
        return MethodInvocation.class;
    }

    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        InterceptorStatusToken token = super.beforeInvocation(mi);

        Object result;
        try {
            result = mi.proceed();
            System.out.println(result);
        } finally {
            super.finallyInvocation(token);
        }
        return super.afterInvocation(token, result);
    }

    @Override
    public AspectMetadataSource obtainAspectMetadataSource() {
        return this.aspectMetadataSource;
    }
}

源码

源码后续放上。。。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值