美文网首页
8.spring5源码分析-AOP与aspectj

8.spring5源码分析-AOP与aspectj

作者: 求索 | 来源:发表于2020-03-20 23:52 被阅读0次

如果你没有把握做到,最好就不要承诺,你什么也不承诺,至少别人不会看不起你。

几个概念

  • 横切关注点:对哪些方法进行拦截,拦截后怎么处理,这些关注点称之为横切关注点
  • Aspect(切面):用于定义切入点和通知的类
  • Joint point(连接点):程序执行过程中明确的点,一般是方法的调用。被拦截到的点,在Spring只支持方法类型的连接点。
  • Pointcut(切点):表示一组 joint point,这些 joint point 或是通过逻辑关系组合起来,或是通过通配、正则表达式等方式集中起来,它定义了相应的 Advice 将要发生的地方。
  • Advice(增强):AOP在特定的切入点上执行的增强处理,有before(前置),after(后置),afterReturning(最终),afterThrowing(异常),around(环绕)。
  • Target(目标对象):织入 Advice 的目标对象.。
  • Weaving(织入): 将切面应用到目标对象并导致代理对象创建的过程
  • introduction(引入):在不修改代码的前提下,引入可以在运行期为类动态地添加一些方法或字段

案例

@Aspect
public class LogAspect {
   @Pointcut("@annotation(com.demo.Log)")
    private void pointcut() {
    }
    @AfterReturning(value = "pointcut()", returning = "result")
    public void doBefore(JoinPoint joinPoint, Object result) {
   }
}

这里 LogAspect 通过 @Aspect 注解声明了一个切面,该切面用于日志处理。
@annotation(com.demo.Log) 定义了一系列连接点,然后通过 @Pointcut 切入。 @AfterReturning 用于通知程序什么时候调用注解,并实现代理操作。

AOP 概念思维导图

8.AOP思维导图.png

前面概念介绍了,那么Spring中如何实现AOP呢?

静态代理

静态代理是程序实现时,直接写入代码的,代理类和实现类是固定不可变的。

public interface HelloWord{
    void hello();
} 
public class HelloWordImpl implements HelloWord{
    //切入点
    @Override
    public void hello(){
        System.out.println("hello!");
    }
}
public class HelloWordProxy{
    private HelloWord helloWord;
    public HelloWordProxy(HelloWord demo){
        helloWord=demo;
    }
    public void hello(){
        System.out.println("before");
        helloWord.hello();
        System.out.println("end");
    }
}
public static void main(String ... args){
    HelloWord src=new HelloWordImpl();
    HelloWord proxy=new HelloWordProxy(src);
    proxy.hello();
}

上面代码是静态代理实现AOP的基本思路,HelloWordProxy 代理中 在调用 hello 前与后都做了输出处理,可以理解为一种环绕模式。

动态代理

先看一个 Cglib代理:

public static class HelloWord   {
    public void hello(){
        System.out.println("hello!");
    }
}
public static void main(String ... args){
    Enhancer enhancer=new Enhancer();
    enhancer.setSuperclass(HelloWord.class);
    enhancer.setCallback((MethodInterceptor) (
            obj, method, methodArgs, methodProxy) -> {
        System.out.println("before");
        Object result =methodProxy.invokeSuper(obj,methodArgs);
        System.out.println("after");
        return result;
    });
    HelloWord helloWord=(HelloWord) enhancer.create();
    helloWord.hello();
}

程序输出:

before
hello!
after

可以看的这里通过 MethodInterceptor 方法实现环绕通知。

spring aop 实现原理

  • ProxyFactory
  • ProxyFactoryBean


    8.ProxyFactoryBean.png

相关文章

网友评论

      本文标题:8.spring5源码分析-AOP与aspectj

      本文链接:https://www.haomeiwen.com/subject/mulushtx.html