spring

Posted newlx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring相关的知识,希望对你有一定的参考价值。

简要记录下ProxyFactoryBean的分析。

proxyFactoryBean 里面,对于Advice类,如MethodBeforeAdvice,AfterRetruningAdvice,ThrowsAdvice 都会转化为MethodInterceptor再起作用

interceptorNames 属性里面的参数,如果是Advisor(包含一个起作用的Advice,和一个限定范围的Pointcut),直接返回,存入AdvicedSupport里面去,

如果是MethodInterceptor或者是以上三类Advice的子类,转化为DefaultPointcutAdvice 后,存入AdvicedSupport的数组里面。

public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
        List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3);
        Advice advice = advisor.getAdvice();
        if (advice instanceof MethodInterceptor) {
            interceptors.add((MethodInterceptor) advice);
        }
        for (AdvisorAdapter adapter : this.adapters) {
            if (adapter.supportsAdvice(advice)) {
                interceptors.add(adapter.getInterceptor(advisor));
            }
        }
        if (interceptors.isEmpty()) {
            throw new UnknownAdviceTypeException(advisor.getAdvice());
        }
        return interceptors.toArray(new MethodInterceptor[interceptors.size()]);
    }

上面代码就是对于特定的Advisor获取methodInterceptor数组,对于之AdvisorAdapter,这个类的作用就是将Advice转化为MethodInterptor。以下面代码分析。

class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {
    MethodBeforeAdviceAdapter() {
    }

    public boolean supportsAdvice(Advice advice) {
        return advice instanceof MethodBeforeAdvice;
    }

    public MethodInterceptor getInterceptor(Advisor advisor) {
        MethodBeforeAdvice advice = (MethodBeforeAdvice)advisor.getAdvice();
        return new MethodBeforeAdviceInterceptor(advice);
    }
}

对于getInterceptor方法,参数advisor实际上就是之前转化的pointcutAdvice,然后看MethodBeforeAdviceInterceptor,

public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable {

    private MethodBeforeAdvice advice;


    /**
     * Create a new MethodBeforeAdviceInterceptor for the given advice.
     * @param advice the MethodBeforeAdvice to wrap
     */
    public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
        Assert.notNull(advice, "Advice must not be null");
        this.advice = advice;
    }

    public Object invoke(MethodInvocation mi) throws Throwable {
        this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
        return mi.proceed();
    }

}

实际上就是插入了advice.before的代码,然后继续调mi.proceed(),驱动methodInteceptor链往下调用。

以上是关于spring的主要内容,如果未能解决你的问题,请参考以下文章

Spring boot:thymeleaf 没有正确渲染片段

What's the difference between @Component, @Repository & @Service annotations in Spring?(代码片段

spring练习,在Eclipse搭建的Spring开发环境中,使用set注入方式,实现对象的依赖关系,通过ClassPathXmlApplicationContext实体类获取Bean对象(代码片段

Spring Rest 文档。片段生成时 UTF-8 中间字节无效 [重复]

解决spring-boot启动中碰到的问题:Cannot determine embedded database driver class for database type NONE(转)(代码片段

一张图帮你记忆,Spring Boot 应用在启动阶段执行代码的几种方式