Spring AOP

2020-01-04  本文已影响0人  茶理思

注:本篇原自学习记录于周冠亚、黄文毅的《Spring 5企业级开发实战》

AOP(Aspect Oriented Programming,面向切面编程)


动态代理,相对于静态代理而提出了的设计模式
Spring中,有两种动态代理:JDK、CGLIB
静态代理,一个代理类只能代理一个对象
JDK动态代理,动态生成,被代理对象必须实现接口 InvocationHandler
CGLIB动态代理,直接对Java类进行代理,需实现接口 MethodInterceptor

代理,给目标对象提供一个代理对象,通过代理对象去控制目标对象
怎么做到的呢,设计模式+反射

// JDK 动态代理为例
public interface Animal { 
    void eat();
}
public class Dog implements Animal {
    @Override
    public void eat() {
        System.out.println("Dog需要吃骨头");
    }
}
public class AnimalInvocationHandler implements InvocationHandler {
    /**
     * 被代理对象
     */
    private Object target;

    /**
     * 绑定业务对象并返回一个代理类
     * @param target
     * @return
     */
    public Object bind(Object target) {
        this.target = target;
        //通过反射机制,创建一个代理类对象实例并返回。用户进行方法调用时使用
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    }

    /**
     * 接口方法
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result=null;
        //方法执行前加一段逻辑
        System.out.println("——————调用前处理——————");
        //调用真正的业务方法
        result=method.invoke(target, args);
        //方法执行前加一段逻辑
        System.out.println("——————调用后处理——————");
        return result;
    }
}
public class JDKDynamicProxyDemo {
    public static void main(String[] args) {
        //被代理对象
        Dog dog = new Dog();
        //动态代理类对象
        AnimalInvocationHandler animalInvocationHandler = new AnimalInvocationHandler();
        //代理对象
        Animal proxy = (Animal) animalInvocationHandler.bind(dog);
        proxy.eat();
    }
}

以上就是Spring AOP的基本原理,只是Spring不需要开发人员自己维护代理类,其已帮开发人员生成了代理类。Spring AOP的实现是通过在程序运行时,根据具体的类对象和方法等信息动态地生成了一个代理类的class文件的字节码,再通过ClassLoader将代理类加载到内存中,最后通过生成的代理对象进行程序的方法调用。


AOP是OOP的补充、完善

OOP:Object Oriented Programming

为啥会有AOP?
在OOP中,非核心、又通用的功能(日志、监控等)代码散落各处,重复且不利复用
将多个对象的公共模块分装成一个模块,形成一个Aspect

相关概念

方法拦截,增强原来方法

横切关注点的抽象

程序执行中特定的点,Spring只支持方法类型的连接点,所有Spring AOP的连接点总表示一个方法的执行

切入点是匹配连接点的拦截规则,切入点表达式如何和连接点匹配是AOP的核心,Spring默认使用AspectJ切入点语法

拦截特定的连接点之后的动作

需进行增强的对象

把切面作用到目标对象,然后产生一个代理对象的过程。

不需为类实现一个接口,就能使用接口中的方法。


AOP实现

JDK
CGLIB

Q:execution表达式


image.png
@Pointcut("execution(* com.test.aop.cglib.annotation.*.*(..))")
public void location() {}

返回类型是*
方法名是在那个包下的都可以
参数是任意的


基于Spring AOP的实战

image.png

Spring集成AspectJ

AspectJ是一个面向切面的框架,其可以生成遵循Java字节码规范的Class文件。
Spring AOP和AscpectJ之间的关系:Spring使用了和AspectJ一样的注解,并使用AspectJ来做切入点解析和匹配。但是Spring AOP运行时并不依赖于AspectJ的编译器或者织入器等特性。

image.png

this不仅可以匹配Listener接口中定义的方法,而且还可以匹配FoodFactory中的方法
target仅仅匹配Listener中定义的方法。


Spring AOP的实现原理

Spring AOP的实现是通过创建目标对象的代理类,并对目标对象进行拦截来实现的

image.png
上一篇下一篇

猜你喜欢

热点阅读