摘要

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

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

关键词:Spring,AOP

一、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提供了两种方式来生成代理对象:JDKProxy和CGLIB
使用方式由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:AOP的更多相关文章

  1. Spring:AOP面向切面编程

    AOP主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果. AOP是软件开发思想阶段性的产物,我们比较熟悉面向过程O ...

  2. spring:AOP面向切面编程(注解)03

    使用注解写aop时最好使用环绕通知写 切面类: /** * 用于记录日志的工具类,它里面提供了公共的代码 */ @Component("logger") @Aspect //表示当 ...

  3. spring:AOP面向切面编程02

    参考: https://blog.csdn.net/jeffleo/article/details/54136904 一.AOP的核心概念AOP(Aspect Oriented Programming ...

  4. 理解Spring:AOP的原理及手动实现

    引入 到目前为止,我们已经完成了简易的IOC和DI的功能,虽然相比如Spring来说肯定是非常简陋的,但是毕竟我们是为了理解原理的,也没必要一定要做一个和Spring一样的东西.到了现在并不能让我们松 ...

  5. Spring:Aop before after afterReturn afterThrowing around 的原理

    在写这篇文章前,在网上看了一下大多数的文章,在说这一块时,都是用语言来表达的.before.after.afterReturn.afterThrowing 这四个用语言是可以说清楚的,但 around ...

  6. 使用spring:aop中修改增强方法中的参数

    大家都知道,在增强方法中,使用jp.getArgs()[index]可以获取传进来的参数,但是参数传进来之后,怎么改变它的值呢? 因为jp.getArgs()[index]获取到的只是数据的备份,所以 ...

  7. 深入浅出学习Spring框架(三):AOP 详解

    AOP的英文解释——AOPAspect Oriented Programming面向切面编程.主要目的是通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术. 在反 ...

  8. Spring使用 --- 基本概念(二):AOP,面向方面编程

    Table of Contents 什么是面向方面编程 怎样使用 什么时候使用 好处 本文讲述sprint的第二个基本概念: AOP,即面向方面编程 什么是面向方面编程 软件项目中,日志系统等服务系统 ...

  9. Java框架spring 学习笔记(十二):aop实例操作

    使用aop需要在网上下载两个jar包: aopalliance.jar aspectjweaver.jar 为idea添加jar包,快捷键ctrl+shift+alt+s,打开添加jar包的对话框,将 ...

随机推荐

  1. 京东饭粒捡漏V1.0.7

    20180614 更新 V1.0.71.修改捡漏策略 功能介绍1.京东商城专用,支持饭粒模式下单,自己获得京豆返利 2.捡漏模式:帮助用户监控抢购商品,有库存的时候进行抢单,主要是通过添加商品ID - ...

  2. mac下 chmod 不了文件,可以右键查看文件简介处修改权限

  3. WPF 和 百度 eChart 交互

    https://blog.csdn.net/defrt4/article/details/52689052

  4. piggy.lzo

    编译内核的时候出现错误:arch/arm/boot/compressed/piggy.lzo.S:4: Error: file not found: arch/arm/boot/compressed/ ...

  5. 搭建zookeeper+kafka集群

      搭建zookeeper+kafka集群 一.环境及准备 集群环境:   软件版本: 部署前操作: 关闭防火墙,关闭selinux(生产环境按需关闭或打开) 同步服务器时间,选择公网ntpd服务器或 ...

  6. flutter 入口文件配置路由+加载页面

    入口文件配置路由 1.路由信息 -- 加载页面 ,通常用于显示新的内容或者广告,加载完成之后进入主页面 -- 主页面 /app 2.配置页面  main.dart main.dart // main ...

  7. Appium java环境搭建(Windows版)

    注意:如果初次学习appium的话,则需要你做好准备因为安装过程并不简单 1.安装appium Appium 官方网站:http://appium.io/ 安装Appium之前需要先安装node.js ...

  8. iOS应用图标AppIcon

    应用图标需求:(像素px) 29pt:      58*58 ( @2x ) 87*87 ( @3x ) 40pt:      120*120 ( @2x ) 180*180 ( @3x ) 60pt ...

  9. Error occurred during initialization of VM Could not reserve enough space for object heap

    Error occurred during initialization of VM Could not reserve enough space for object heap Java虚拟机(JV ...

  10. RocketMQ源码分析:(二)消息发送的三种方式

    1. 同步传输(可靠,适用于重要的通知消息.短信通知.短信营销系统等) package com.miaoying.rocketmq.client; import lombok.extern.slf4j ...