Spring:AOP

本贴最后更新于 2122 天前,其中的信息可能已经时移世易

摘要

本文内容为我在网上搜集 Spring AOP 资料的汇总、摘抄。

AOP 是一种编程思想,其对不同对象进行了横向的抽象,将不同对象的、和主流程无关的公共逻辑抽象出来以方便维护。AOP 的实现基础为 AOP 动态代理,动态代理又可以由 JDK 动态代理和 CGLIB 实现。Spring 中 AOP 的编程模型是定义组件、定义切入点、定义增强功能。

关键词:SpringAOP

一、AOP 简介

1. 什么是 AOP

AOP(Aspect Oriented Programming,面向切面编程),横向抽象的一种编程思想,是对 OOP(Object Oriented Programming,面向对象编程)的补充和完善。

OOP 中的基本三个基本特征:封装继承多态,其对象关系的描述是纵向的,对于分散在不同对象、同一层面的代码却无能为力。比如需要在代码开头和结尾处都打印相同的日志,就没有办法描述这种业务了。

AOP 则可以解决这个问题,它可以将不同代码同一层次的业务无关的公共逻辑抽象出来,再把代码逻辑织入到对应的切面点,这样就可以减少重复代码,以及方便维护了。

AOP 的应用可以有权限认证、日志、事务等。

2. AOP 的一些概念

概念 解释
核心关注点 业务处理的主要流程为核心关注点
横切关注点 与业务处理主要流程不相关的部分为横切关注点(特征:分散
切面(aspect) 切面为对横切关注点的抽象
连接点(joinpoint) 被拦截的点,在 Spring 中为拦截到的方法
切入点(pointcut) 对连接点进行拦截的定义
通知(adivce) 指拦截到连接点后,要执行的代码。可以分为:前置后置异常最终环绕
目标对象 代理的目标对象
织入(weave) 将切面应用到目标对象,产生代理对象的过程。(即将行为织入到业务流程中)
引入(introduction) 不修改代码,在运行期(runtime)将类动态添加一些方法或字段。

二、Spring 中 AOP 的实现原理

Spring AOP 实现的基石在于代理,也就是应用 AOP 后实际上是生成 AOP 代理对象,Spring 中 AOP 代理及其依赖关系由 IoC 容器负责生成、管理。

代理对象=目标对象 + 切面处理(通知)

1. 代理

1.1 静态代理

静态代理产生于代码的编译阶段,一旦代码运行就不可改变;

// 接口
public interface IPerson {
  public void doSth();
}

// 接口实现
public class Person implements IPerson {
  public void doSth(){
    System.out.println("do sth");
  }
}

// 代理实现
public class PersonProxy {
  private IPerson person;
  
  public PersonProxy(IPerson person) {
    this.person = person;
  }
  
  public void doSth() {
    System.out.println("before do sth");
    person.doSth();
    System.out.println("after do sth");
  }
}
public static void main(String[] args) {
  PersonProxy personProxy = new PersonProxy(new Person());
  personProxy.doSth();
}
/*
result console:
before do sth
do sth
after do sth
*/

1.2 动态代理

这里特指 JDK 动态代理,区别与静态代理,动态代理产生于代码的运行时阶段。JDK 动态代理利用了 Java 的反射机制,生成一个实现代理接口的类,调用具体方法由 InvocationHandler 来处理。这种动态代理需要依赖接口来实现。

public class PersonProxy implements InvocationHandler {
  private Object delegate;

  public Object bind(Object delegate) {
    this.delegate = delegate;
    // 指明类加载器、指明生成哪个对象的代理对象(接口指定)、指明Handler
    return Proxy.newProxyInstance(delegate.getClass().getClassLoader(), delegate.getClass().getInterfaces(), this);
  }
  
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    Object result = null;
    try {
      System.out.println("before do sth");
      result = method.invoke(delegate, args);
      System.out.println("after do sth");
    } catch(Exception e) {
      throw e;
    }
	return result;
  }
}
public static void main(String[] args) {
  PersonProxy personProxy = new PersonProxy();
  IPerson iPerson = (IPerson) personProxy.bind(new Person());
  iPerson.doSth();
}
/*
result console:
before do sth
do sth
after do sth
*/

1.3 CGLIB

如果没有接口,动态代理可以借助 CGLIB 来实现,它可以用生成代理目标子类(因此不能代理 final 修饰的类)的方式来实现代理,而不是接口,规避来接口的局限性。

实现 MethodInterceptor 接口来实现。

public class PersonProxy implements MethodInterceptor {
  private Object delegate;
  public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
    System.out.println("before do sth");
    Object result = methodProxy.invokeSuper(method, args);
    System.out.println("after do sth");
    return result;
  }
  public static Person getProxyInstance() {
    Enhancer enhancer = new Enhancer();
    enhancer.setSuperclass(Person.class);
    enhancer.setCallback(new PersonProxy());
    return (Person) enhancer.create();
  }
}
public static void main(String[] args) {
  Person person = PersonProxy.getProxyInstance();
  person.doSth();
}
/*
result console:
before do sth
do sth
after do sth
*/

2. Spring AOP 代理创建规则

Spring 提供了两种方式来生成代理对象:JDKProxyCGLIB
使用方式由 AopProxyFactory 根据 AdvisedSupport 对象配置来决定。

代理默认创建规则:

  1. 如果目标类是接口,则使用 Java 动态代理创建 AOP 代理;
  2. 如果目标类不是接口,则使用 Cglib 生成代理;

三、在 Spring 中使用 AOP

AOP 编程步骤:

  1. 定义普通业务组件;
  2. 定义切入点(切入点和业务组件的对应关系可以是一对多);
  3. 定义增强处理,即为普通业务组件织入的动作;

1. 使用 XML 文件配置 AOP

参考:Spring 中基于 AOP 的 XML 架构

2. 使用注解配置 AOP

参考:Spring 中基于 AOP 的 @AspectJ

四、总结

  1. AOP(Aspect Oriented Programming,面向切面编程),横向抽象的一种编程思想,是对 OOP(Object Oriented Programming,面向对象编程)的补充和完善。
  2. Spring AOP 实现的基石在于代理,也就是应用 AOP 后实际上是生成 AOP 代理对象,Spring 中 AOP 代理及其依赖关系由 IoC 容器负责生成、管理。
  3. Spring 中 AOP 的编程模型是定义组件、定义切入点、定义增强功能。

参考资料

  1. Spring3:AOP
  2. Spring AOP 原理分析一次看懂
  3. Spring-aop 全面解析(从应用到原理)
  4. Spring 的两种代理 JDK 和 CGLIB 的区别浅谈
  5. Spring 教程
  • Spring

    Spring 是一个开源框架,是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

    942 引用 • 1458 回帖 • 117 关注
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3169 引用 • 8208 回帖

相关帖子

回帖

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...