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. AngularJS ——ngResource、RESTful APIs 使用

    这篇文章里,用以下两个情景用例来解释: 保存/持久化 新的数据对象 更新存在的数据对象 代码片段包含了AngularJs代码和Spring MVC代码,以能够让你简单快速的上手. 想要$resourc ...

  2. Atitit.ati dwr的原理and设计 attilax 总结 java php 版本

    Atitit.ati dwr的原理and设计 attilax 总结 java php 版本 1. dwr的优点相对于ajax来说..1 2. DWR工作原理1 3. Dwr的架构2 4. 自定义dwr ...

  3. securtCRT右键复制功能配置

    Options->Global Options->Terminal 在右边选择或者取消“Copy on select”和“Paste on right button”的勾选即可打开或者关闭 ...

  4. java性能监控工具:jmap命令详解

    .命令基本概述 Jmap是一个可以输出所有内存中对象的工具,甚至可以将VM 中的heap,以二进制输出成文本.打印出某个java进程(使用pid)内存内的,所有‘对象’的情况(如:产生那些对象,及其数 ...

  5. PHP学习笔记(7)验证码优化

    php代码,主要把RGB改成随机生成,不是之前固定的七种颜色了: <?php // ob_clean(); header("content-type:image/png"); ...

  6. oracle,mysql分页

    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-/ ...

  7. SPI_FLASH时序描述及驱动编程

    推荐 分享一个朋友的人工智能教程,零基础!通俗易懂!希望你也加入到人工智能的队伍中来! http://www.captainbed.net/strongerhuang Ⅰ.写在前面 前面文章讲述过关于 ...

  8. Ubuntu Apache配置及开启mod_rewrite模块

    刚刚将服务器系统从CentOS换成Ubuntu,将MySQL,Apache,PHP和Wordpress安装好后,发现打开主页是正常的,但是打开文章页面时出现错误.因为使用了自定义的固定链接设置,那自然 ...

  9. centos7.2 安装 Elasticsearch5.2

    打算上全文检索,就找到了找个产品,开始研究下…… 1.官网地址: https://www.elastic.co/guide/en/elasticsearch/reference/5.2/install ...

  10. expr判断整数是相加的值,返回命令的返回值$? 是0,但是少数情况是1,例如1 + -1 ,$? 的结果是1 ,判断要大于1最准确

    [root@m01 ~]# expr 1 + 12[root@m01 ~]# echo $?0[root@m01 ~]# echo 1 - 51 - 5[root@m01 ~]# expr 1 - 5 ...