1. AOP 的概述

  • AOP, Aspect Oriented Programming, 面向切面编程;
  • 通过预编译方式和运行期动态代理实现程序功能的统一维护的技术;
  • AOP 采取横向抽取机制,取代了传统纵向继承体系重复性代码(性能监视,事务管理,安全检查,缓存);
  • AOP 可以在不修改源代码的前提下,对程序进行增强;

2. AOP 的底层实现

  1. Spring 框架的AOP技术底层采用的是代理技术,代理方式分为:

    • 基于JDK的动态代理:必须是面向接口的,只有实现了具体接口的类才能生成代理对象;
    • 基于CGLIB的动态代理: 对于没有实现接口的类,采用生成类的子类的方式;
  2. 基于JDK的动态代理的原理,请参考"动态代理入门"

  3. 基于CGLIB的代理技术(了解)

// 1. 引入Spring 核心开发包, 其中包含CGLIB的开发 jar包,

// 2. 编写相关代码

// CGLIB 代理类
public class MyCglibUtils{
public static BookDaoImpl getProxy(){
// 创建 CGLIB 的核心类
Enhancer enhancer = new Enhancer(); // 设置父类
enhancer.setSuperclass(BookDaoImpl.class); // 设置回调函数, 参数为匿名内部类
enhancer.setCallback(new MethodInterceptor(){
@Override
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy methodProxy) throws Throwable{
if("save".equals(method.getName())){
// 添加新功能(例如记录日志)
System.out.println("开始记录日志...");
} // 目标对象的方法正常执行
return methodProxy.invokeSuper(obj,args);
}
}); // 生成代理对象
BookDaoImpl proxy = (BookDaoImpl)enhancer.create();
return proxy;
}
} public class BookDaoImpl{ public void save(){
System.out.println("保存图书...");
}
} // 测试方法
public class Demo{ // 没有使用代理之前
public void fun2(){
BookDaoImpl dao = new BookDaoImpl();
dao.save();
} // 使用CGLIB代理
public void fun3(){ BookDaoImpl proxy = MyCglibUtils.getProxy();
proxy.save();
}
}

3. Spring 基于AspectJ的AOP开发

1. AOP 的相关术语

  • Joinpoint(连接点): 指那些被拦截到的点,在Spring中,这些点指的是类中的所有方法;
  • Pointcut(切入点): 指我们要对哪些Joinpoint进行拦截,也就是需要增强的方法;
  • Advice(通知/增强): 指拦截到Joinpoint之后,所要做的事情,分为前置通知,后置通知,异常通知,最终通知,环绕通知;
  • Introduction(引介): 是一种特殊的通知; 在不修改类代码的前提下,introduction 可以在运行期为类动态的

    添加一些方法或Field;
  • Target(目标对象): 代理的目标对象;
  • Weaving(织入):是指把增强添加到目标对象,创建新的代理对象的过程;
  • Proxy(代理): 一个类被AOP织入增强后,就产生一个结果代理类;
  • Aspect(切面): 是切入点和通知的结合;
  • 其中,通知需要自己来编写,切入点需要自己来配置;

2. AspectJ的XML方式完成AOP的开发

2.1 导入 jar 包
  • Spring 框架的基本开发包(6个);
  • Spring 的传统AOP的开发包
    • spring-aop-4.3.10.RELEASE
    • org.aopalliance-1.10.0 (在 Spring 依赖包中)
  • aspectJ 的开发包
    • org.aspectj.weave-1.6.8.RELEASE.jar (在 Spring 依赖包中)
    • spring-aspects-4.3.10.RELEASE.jar
2.2 编写 applicationContext.xml 配置文件
// 需要引入具体的AOP的schema约束
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 配置 customerDao -->
<bean id="customerDao" class="cn.itcast.demo.CustomerDaoImpl"/> <!-- 配置切面类 -->
<bean id="myAspectXml" class="cn.itcast.demo.MyAspectXml"/> <!-- 配置 AOP -->
<aop:config>
<!-- 配置切面类: 包含了切入点和通知(类型) -->
<aop:aspect ref="myAspectXml">
<!-- 配置前置通知 -->
<!-- 切入点表达式:
execution(public void cn.itcast.demo.CustomerDaoImpl.save()) -->
<aop:before method="log"
pointcut="execution(public void cn.itcast.demo.CustomerDaoImpl.save())"/> </aop:aspect>
</aop:config>
</beans>
2.3 创建包结构,编写具体的接口和实现类
  • cn.itcast.demo

    • CustomerDao: 接口
    • CustomerDaoImpl: 实现类
// CustomerDao.java  接口
public interface CustomerDao{
public void save();
public void update();
} // CustomerDaoImpl.java 实现类
public class CustomerDaoImpl implements CustomerDao{
public void save(){
System.out.println("保存客户...");
} public void update(){
System.out.println("修改客户...");
}
} // 测试类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public void Demo{ @Resource(name="customerDao")
private CustomerDao customerDao; @Test
public void fun(){
customerDao.save();
customerDao.update();
}
} // 需求: 使用AOP技术,在不改变源代码的情况下,增强 save() 方法
// 创建切面类
public class MyAspect{ // 通知(具体的增强)
public void log(){
System.out.println("记录日志...");
}
} // 然后在 applicationContext.xml 中配置切面类, 即可完成增强

3. AOP 的切入点表达式

  1. 格式: execution([修饰符] 返回值类型 包名.类名.方法名(参数))

    • 修饰符 public 可以省略不写;
    • 返回值类型不能省略的,可以使用 * 代替,表示返回值为任意类型;
    • 包名,以 cn.itcast.demo.CustomerDaoImpl.save() 为例
      • cn是不能省略的,可以使用 * 代替;
      • 中间的包名可以使用 * 代替;
      • 如果向省略掉中间的包名,可以使用"..",表示任意包下的 save 方法;
    • 类名可以使用 * 代替,也有类似的写法 *DaoImpl;
    • 方法可以使用 * 代替,也有类似的写法 save*()
    • 参数如果是一个参数可以使用 * 代替,如果向代表任意参数,可以使用".."

4. AOP 的通知类型

  1. 前置通知

    • 在目标类的方法执行之前执行;
    • 具体配置格式: <aop:before method="方法名" pointcut="被增强的方法"/>
    • 应用: 可以对方法的参数来做校验;
  2. 最终通知
    • 在目标类的方法执行之后执行,如果程序出现了异常,最终通知也会执行;
    • 具体配置格式: <aop:after method="方法名" pointcut="被增强的方法"/>
    • 应用:释放资源;
  3. 后置通知
    • 方法正常执行后的通知;
    • 具体配置格式: <aop:after-returning method="方法名" pointcut="被增强的方法"/>
    • 应用: 可以修改方法的返回值;
  4. 异常抛出通知
    • 在抛出异常后的通知;
    • 具体配置格式: <aop:after-throwing method="方法名" pointcut="被增强的方法"/>
    • 应用:包装异常信息;
  5. 环绕通知
    • 方法的执行前后执行;
    • 具体配置格式: <aop:around method="方法名" pointcut="被增强的方法"/>
    • 默认情况下,目标对象的方法不能执行,需要手动让目标对象的方法执行;
// 环绕通知的增强方法
public void around(ProceedingJoinPoint joinPoint){
System.out.println("环绕通知1...."); // 手动执行目标方法
try{
joinPoint.proceed();
}catch(Exception e){
throw new RuntimeException(e);
} System.out.println("环绕通知2....");
}

参考资料

Spring 框架的核心功能之AOP技术的更多相关文章

  1. Spring框架的核心功能之AOP技术

     技术分析之Spring框架的核心功能之AOP技术 AOP的概述        1. 什么是AOP的技术?        * 在软件业,AOP为Aspect Oriented Programming的 ...

  2. Spring框架的核心功能之AOP概述

    1. 什么是AOP的技术? * 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程 * AOP是一种编程范式,隶属于软工范畴,指导开发者如何组织程序结构 ...

  3. Spring框架学习(9)AOP技术理解与使用

    内容源自:AOP技术理解与使用 一.什么是AOP? aop技术是面向切面编程思想,作为OOP(面向对象编程)的延续思想添加到企业开发中,用于弥补OOP开发过程中的缺陷而提出的编程思想. AOP底层也是 ...

  4. 控制反转是Spring框架的核心。

    早在2004年,Martin Fowler就提出了“哪些方面的控制被反转了?”这个问题.他总结出是依赖对象的获得被反转了.基于这个结论,他为控制反转创造了一个更好的名字:依赖注入.许多非凡的应用(比H ...

  5. Java轻量级业务层框架Spring两大核心IOC和AOP原理

    IoC(Inversion of Control): IOC的基本概念是:不创建对象,但是描述创建它们的方式.在代码中不直接与对象和服务连接,但在配置文件中描述哪一个组件需要哪一项服务.容器负责将这些 ...

  6. Spring框架的核心模块的作用

    Spring框架由7个定义良好的模块(组件)组成,各个模块可以独立存在,也可以联合使用. (1)Spring Core:核心容器提供了Spring的基本功能.核心容器的核心功能是用Ioc容器来管理类的 ...

  7. spring两个核心IOC、AOP

    Spring是一个开放源代码的设计层面框架,他解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用.Spring是于2003 年兴起的一个轻量级的Java 开发框架,由 ...

  8. Spring框架各模块功能介绍

    一. Spring是什么? Spring由Rod johnson开发: 是一个非常活跃的开源框架: 它帮助分离项目组件(对象)之间的依赖关系: 它的主要目的是简化企业开发 二. Spring的核心概念 ...

  9. spring 框架的核心总结

    最近在学习Java语言,从而也学习了SpringFramework 这个大名鼎鼎的框架.从而做一些的记录. 题外话: 学习过几种不同的语言,后来知道所有的编程语言里所有的概念翻来覆去都是一样的事物,只 ...

随机推荐

  1. 多线程-Thread与Runnable源码分析

    Runnable: @FunctionalInterface public interface Runnable { /** * When an object implementing interfa ...

  2. Apollo配置中心转

    尊重原创,本文转自:https://www.cnblogs.com/FlyAway2013/p/8811385.html 前我们项目,所有的配置基本都是通过本地properties 文件进行配置的,比 ...

  3. Git-查看远程分支、本地分支、创建分支

    1.查看本地分支 $ git branch * br-2.1.2.2 master 2.查看远程分支 $ git branch -r origin/HEAD -> origin/master o ...

  4. 蓝牙(CoreBluetooth)-中心设备(客户端)

    蓝牙(CoreBluetooth)-中心设备(客户端) 蓝牙客户端-中心设备 主要内容 1. 创建`中央管理器` 2. 发现并且连接外设 3. 寻找连接上的外设数据 4. 发送读或写`特征值`的请求 ...

  5. js 正则表达式 验证小数点后几位

    function IsFloatByBit (value, state, bit) {             if (state == false) {                 var re ...

  6. Freemarker自定义方法

    在项目中有一个需求,每个物品有一个guid,存在数据库中,而在页面上需要显示一个对应的业务数据值,暂且叫做serverId,serverId是通过guid移位计算得来.serverId只需要显示,后台 ...

  7. Python Excel 导入导出【转】

    一.安装xlrd模块 到python官网下载http://pypi.python.org/pypi/xlrd模块安装,前提是已经安装了python 环境. 二.使用介绍 1.导入模块 import x ...

  8. Tuning 04 Sizing the Buffer Cache

    Buffer Cache 特性 The buffer cache holds copies of the data blocks from the data files. Because the bu ...

  9. 安装vm虚拟机

    1.本次win10系统安装vmware workstation  下载地址:http://www.ihacksoft.com/vmware-workstation-10-0-4.html 2.镜像使用 ...

  10. Jmeter接口测试系列之参数化方法

    至于参数化的用途,我这里就不多说了,本文主要介绍最全.最强大的参数化方法,对参数化有一个彻底的认识,这里提供了多种参数化方法 1.jmeter参数化之用户变量   在测试计划里面添加一个用户自定义的变 ...