SpringAOP基础组件Advisor

导读:本篇文章讲解 SpringAOP基础组件Advisor,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

相关阅读

简介

持有AOP Advice和决定Advice适用性的过滤器(比如Pointcut)的基础接口;
Spring AOP基于符合AOP拦截API的MethodInterceptor支持通知,Advisor接口允许支持不同类型的通知,比如:前置通知、后置通知这些不需要通过拦截器实现的通知;

源码

public interface Advisor {

    // 空通知
    Advice EMPTY_ADVICE = new Advice() {};

    // 获取通知,可以是拦截器、前置通知、抛出异常通知等
    Advice getAdvice();

    // 是否和每个被通知的实例相关
    // 当前框架还未用到该方法,可以通过单例/多例,或者恰当的代理创建来确保Advisor的生命周期正确
    boolean isPerInstance();
}

实现子类

Advisor

IntroductionAdvisor

简介

支持AOP 引介功能的Advisor的基础接口;

核心代码

public interface IntroductionAdvisor extends Advisor, IntroductionInfo {

    // 获取决定引介适用性的类过滤器
    ClassFilter getClassFilter();

    // 校验被通知的接口是否可以应用该IntroductionAdvisor
    void validateInterfaces() throws IllegalArgumentException;
}

DefaultIntroductionAdvisor

简介

IntroductionAdvisor的简单实现,默认地应用引介到任意类型;

核心代码

public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFilter, Ordered, Serializable {

    private final Advice advice;

    private final Set<Class<?>> interfaces = new LinkedHashSet<>();


    public DefaultIntroductionAdvisor(Advice advice, @Nullable IntroductionInfo introductionInfo) {
        // 校验Advice
        Assert.notNull(advice, "Advice must not be null");
        this.advice = advice;
        if (introductionInfo != null) {
            Class<?>[] introducedInterfaces = introductionInfo.getInterfaces();
            if (introducedInterfaces.length == 0) {
                throw new IllegalArgumentException(
                        "IntroductionInfo defines no interfaces to introduce: " + introductionInfo);
            }
            // 应用引介接口信息
            for (Class<?> ifc : introducedInterfaces) {
                addInterface(ifc);
            }
        }
    }

    public DefaultIntroductionAdvisor(DynamicIntroductionAdvice advice, Class<?> ifc) {
        // 校验Advice
        Assert.notNull(advice, "Advice must not be null");
        this.advice = advice;
        addInterface(ifc);
    }

    public void addInterface(Class<?> ifc) {
        Assert.notNull(ifc, "Interface must not be null");
        if (!ifc.isInterface()) {
            throw new IllegalArgumentException("Specified class [" + ifc.getName() + "] must be an interface");
        }
        this.interfaces.add(ifc);
    }

    @Override
    public Class<?>[] getInterfaces() {
        return ClassUtils.toClassArray(this.interfaces);
    }

    @Override
    public void validateInterfaces() throws IllegalArgumentException {
        for (Class<?> ifc : this.interfaces) {
            // 校验当前Advice是否支持所有的interfaces
            if (this.advice instanceof DynamicIntroductionAdvice &&
                    !((DynamicIntroductionAdvice) this.advice).implementsInterface(ifc)) {
                throw new IllegalArgumentException("DynamicIntroductionAdvice [" + this.advice + "] " +
                        "does not implement interface [" + ifc.getName() + "] specified for introduction");
            }
        }
    }

    @Override
    public Advice getAdvice() {
        return this.advice;
    }

    @Override
    public boolean isPerInstance() {
        return true;
    }

    @Override
    public ClassFilter getClassFilter() {
        // 返回自身
        return this;
    }

    @Override
    public boolean matches(Class<?> clazz) {
        // 匹配任意类型
        return true;
    }
}

PointcutAdvisor

简介

Pointcut驱动的Advisor的基础接口;
含盖了除引介Advisor外几乎所有的Advisor

核心代码

public interface PointcutAdvisor extends Advisor {

    // 获取Pointcut
    Pointcut getPointcut();
}

StaticMethodMatcherPointcutAdvisor

简介

同时作为StaticMethodMatcherPointcutAdvisor的基础抽象类;

核心代码

public abstract class StaticMethodMatcherPointcutAdvisor extends StaticMethodMatcherPointcut
        implements PointcutAdvisor, Ordered, Serializable {

    // 默认空通知
    private Advice advice = EMPTY_ADVICE;


    public StaticMethodMatcherPointcutAdvisor(Advice advice) {
        // 校验Advice
        Assert.notNull(advice, "Advice must not be null");
        this.advice = advice;
    }

    @Override
    public Advice getAdvice() {
        return this.advice;
    }

    @Override
    public boolean isPerInstance() {
        return true;
    }

    @Override
    public Pointcut getPointcut() {
        // 返回自身
        return this;
    }
}

AspectJPointcutAdvisor

简介

适配AbstractAspectJAdvicePointcutAdvisor接口;

核心代码

public class AspectJPointcutAdvisor implements PointcutAdvisor, Ordered {

    private final AbstractAspectJAdvice advice;

    private final Pointcut pointcut;


    public AspectJPointcutAdvisor(AbstractAspectJAdvice advice) {
        // 校验Advice
        Assert.notNull(advice, "Advice must not be null");
        this.advice = advice;
        this.pointcut = advice.buildSafePointcut();
    }

    @Override
    public boolean isPerInstance() {
        return true;
    }

    @Override
    public Advice getAdvice() {
        return this.advice;
    }

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

AsyncAnnotationAdvisor

简介

Spring Async功能的实现,支持通过@Async注解和javax.ejb.Asynchronous注解来激活异步方法执行的Advisor

核心代码

public class AsyncAnnotationAdvisor extends AbstractPointcutAdvisor implements BeanFactoryAware {

    private Advice advice;

    private Pointcut pointcut;


    public AsyncAnnotationAdvisor(
            @Nullable Supplier<Executor> executor, @Nullable Supplier<AsyncUncaughtExceptionHandler> exceptionHandler) {

        // 默认支持Async和javax.ejb.Asynchronous,故size为2
        Set<Class<? extends Annotation>> asyncAnnotationTypes = new LinkedHashSet<>(2);
        asyncAnnotationTypes.add(Async.class);
        try {
            asyncAnnotationTypes.add((Class<? extends Annotation>)
                    ClassUtils.forName("javax.ejb.Asynchronous", AsyncAnnotationAdvisor.class.getClassLoader()));
        }
        catch (ClassNotFoundException ex) {
            // If EJB 3.1 API not present, simply ignore.
        }
        // 根据异步执行器和异常处理器生成Advice
        this.advice = buildAdvice(executor, exceptionHandler);
        // 生成Pointcut
        this.pointcut = buildPointcut(asyncAnnotationTypes);
    }

    @Override
    public Advice getAdvice() {
        return this.advice;
    }

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

    protected Advice buildAdvice(
            @Nullable Supplier<Executor> executor, @Nullable Supplier<AsyncUncaughtExceptionHandler> exceptionHandler) {
        // 使用AnnotationAsyncExecutionInterceptor
        AnnotationAsyncExecutionInterceptor interceptor = new AnnotationAsyncExecutionInterceptor(null);
        interceptor.configure(executor, exceptionHandler);
        return interceptor;
    }

    protected Pointcut buildPointcut(Set<Class<? extends Annotation>> asyncAnnotationTypes) {
        ComposablePointcut result = null;
        // 遍历注解类型集合,得到一个ComposablePointcut
        for (Class<? extends Annotation> asyncAnnotationType : asyncAnnotationTypes) {
            // 匹配类,忽略方法(MethodMatcher.TRUE)
            Pointcut cpc = new AnnotationMatchingPointcut(asyncAnnotationType, true);
            // 匹配方法,忽略类(ClassFilter.TRUE)
            Pointcut mpc = new AnnotationMatchingPointcut(null, asyncAnnotationType, true);
            if (result == null) {
                result = new ComposablePointcut(cpc);
            }
            else {
                result.union(cpc);
            }
            result = result.union(mpc);
        }
        // 若不存在注解类型,则认为全匹配
        return (result != null ? result : Pointcut.TRUE);
    }
}

BeanFactoryCacheOperationSourceAdvisor

简介

Spring Cache功能的实现,基于CacheOperationSource实现的Advisor,内部持有Advice实例;

核心代码

public class BeanFactoryCacheOperationSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {

    // 判断当前方法是否有缓存注解,被CacheOperationSourcePointcut用来实现切入点逻辑
    @Nullable
    private CacheOperationSource cacheOperationSource;

    // 使用基于CacheOperationSource的CacheOperationSourcePointcut作为pointcut
    private final CacheOperationSourcePointcut pointcut = new CacheOperationSourcePointcut() {
        @Override
        @Nullable
        protected CacheOperationSource getCacheOperationSource() {
            return cacheOperationSource;
        }
    };

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

BeanFactoryTransactionAttributeSourceAdvisor

简介

Spring 注解驱动的事务管理功能的实现,基于TransactionAttributeSource实现的Advisor,内部持有Advice实例;

核心方法

public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {

    // 判断当前方法是否有@Transactional注解,被TransactionAttributeSourcePointcut用来实现切入点逻辑
    @Nullable
    private TransactionAttributeSource transactionAttributeSource;

    // 使用基于TransactionAttributeSource的TransactionAttributeSourcePointcut作为pointcut
    private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {
        @Override
        @Nullable
        protected TransactionAttributeSource getTransactionAttributeSource() {
            return transactionAttributeSource;
        }
    };

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

TransactionAttributeSourceAdvisor

简介

Spring 注解驱动的事务管理功能的实现,基于TransactionAttributeSource实现的Advisor,内部持有TransactionInterceptor实例;

核心代码

public class TransactionAttributeSourceAdvisor extends AbstractPointcutAdvisor {

    // 被TransactionAttributeSourcePointcut用来实现切入点逻辑
    @Nullable
    private TransactionInterceptor transactionInterceptor;

    // 使用基于TransactionAttributeSource的TransactionAttributeSourcePointcut作为pointcut
    private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {
        @Override
        @Nullable
        protected TransactionAttributeSource getTransactionAttributeSource() {
            return (transactionInterceptor != null ? transactionInterceptor.getTransactionAttributeSource() : null);
        }
    };


    @Override
    public Advice getAdvice() {
        Assert.state(this.transactionInterceptor != null, "No TransactionInterceptor set");
        return this.transactionInterceptor;
    }

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

DefaultPointcutAdvisor

简介

几乎最通用的PointcutAdvisor的实现,可以使用任意类型Pointcut和除引介外任意类型Advice

核心代码

public class DefaultPointcutAdvisor extends AbstractGenericPointcutAdvisor implements Serializable {

    private Pointcut pointcut = Pointcut.TRUE;


    public DefaultPointcutAdvisor(Pointcut pointcut, Advice advice) {
        this.pointcut = pointcut;
        setAdvice(advice);
    }

    public void setPointcut(@Nullable Pointcut pointcut) {
        this.pointcut = (pointcut != null ? pointcut : Pointcut.TRUE);
    }

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

NameMatchMethodPointcutAdvisor

简介

使用NameMatchMethodPointcutAdvisor

核心代码

public class NameMatchMethodPointcutAdvisor extends AbstractGenericPointcutAdvisor {

    private final NameMatchMethodPointcut pointcut = new NameMatchMethodPointcut();


    public NameMatchMethodPointcutAdvisor(Advice advice) {
        setAdvice(advice);
    }

    public void setMappedName(String mappedName) {
        this.pointcut.setMappedName(mappedName);
    }

    public void setMappedNames(String... mappedNames) {
        this.pointcut.setMappedNames(mappedNames);
    }

    public NameMatchMethodPointcut addMethodName(String name) {
        return this.pointcut.addMethodName(name);
    }

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

RegexpMethodPointcutAdvisor

简介

使用AbstractRegexpMethodPointcutAdvisor

核心代码

public class RegexpMethodPointcutAdvisor extends AbstractGenericPointcutAdvisor {

    @Nullable
    private String[] patterns;

    @Nullable
    private AbstractRegexpMethodPointcut pointcut;


    public RegexpMethodPointcutAdvisor(String pattern, Advice advice) {
        setPattern(pattern);
        setAdvice(advice);
    }

    public RegexpMethodPointcutAdvisor(String[] patterns, Advice advice) {
        setPatterns(patterns);
        setAdvice(advice);
    }

    @Override
    public Pointcut getPointcut() {
        synchronized (this.pointcutMonitor) {
            if (this.pointcut == null) {
                this.pointcut = createPointcut();
                if (this.patterns != null) {
                    //设置正则表达式
                    this.pointcut.setPatterns(this.patterns);
                }
            }
            return this.pointcut;
        }
    }

    protected AbstractRegexpMethodPointcut createPointcut() {
        // 使用JdkRegexpMethodPointcut
        return new JdkRegexpMethodPointcut();
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/4787.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!