转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6776247.html 

一:AOP基础概念

(1)通知(增强)Advice

  通知,其实就是我们从众多类中提取出来的重复功能代码。也即是我们切入到某个类的某个方法点处要执行的操作。如:权限验证、日志操作等。

(2)连接点 Join point

    连接点是针对程序运行的类来说的,指:一个类在运行过程中,有哪些点是可以被切入,执行通知操作进行加工的。

(3)切点 Pointcut

  切点是针对连接点的子集。切点 往往与 通知 协同生效,切点是 通知选择切入的连接点 的合集,切点一般用正则表达式来指定。

(4)切面 Aspect

  切面是通知和切点的容器

(5)引入 Introduction

  引入允许我们在不影响原有类的情况下向现有的类添加新方法或属性,从而无需修改这些现有类的情况下,让他们具有新的行为和状态

既然是新增了,又怎么做到不影响原有类呢?我们用 强加一个父类 的方法来实现。

指定类A,为它强加一个父类 类B,类B中定义了新增的一系列方法。由于现在A继承B,所以B中的方法就可以被A调用了。因此,getBean("A")获得A对象a后,就可以用a.fun_of_B()来调用类B中新增的方法了。

(6)织入 Weaving

  织入是指切面在指定的切点处连接到目标对象中,从而创建出一个被通知(增强)过的对象,一般有:编译时织入、类加载时织入、运行时织入。你可以这样理解:一个类A在上面三个织入时期其中一个,经过织入过程,得到了一个加工过的 类A' 。类A'与类A的不同在于,切点处方法的前、后增加了一些操作(那就是通知)。

二:Spring中的AOP实现

AOP有两种实现,分别是预编译实现、运行时实现。SpringAOP底层使用的是运行时实现,但是对预编译实现也有支持。至于什么是预编译实现、运行时实现,放在Java原理深入的博文中进行探究,此处仅学习SpringAOP的使用。

1:定义切面bean类

切面是通知的容器,里面存放了同一模块的通知。例如:日志切面类,里面包含了info、error、warning等不同级别的日志输出方法。

2:注册切面bean

在applicationcontext.xml配置文件中配置这个bean:

<bean id="myaspect" class="路径">
。。。
</bean>

3:配置切面

1)切面的配置有着严格的层次,外层是<aop:config>标签,指明这是AOP配置,然后是<aop:aspect>标签,说明这是一个切面。

<bean id="aspectBean" class="路径">//注册切面bean
。。。
</bean>
<aop:config>
<aop:aspect id="myAspect" ref="aspectBean">//配置一个切面,依赖切面bean
。。。
</aop:aspect>
</aop:config>

2) 在切面标签下,配置这个切面拥有的切入点。切入点是用正则表达式(用 * 代表路径名或方法名,..代表参数列表)来说明的,也可以用完整的路径进行精确的指定。

SpringAOP中只用到了方法作为切入点。更加精细的切入可以自行用运行时动态代理来实现,如:方法内某语句作为切入点。

<bean id="aspectBean" class="路径">
。。。
</bean>
<aop:config>
<aop:aspect id="myAspect" ref="aspectBean">
<aop:pointcut expression="execution(返回值 路径.方法名(..))" id="pointcut_1"/>//配置一个切入点,参数列表为所有情况都匹配
<aop:pointcut expression="execution(返回值 路径.方法名(Type1,Type2)) and args(name1,name2)" id="pointcut_1"/>//精确配置一个切入点,参数列表处为参数类型,args为参数名称 。。。
</aop:aspect>
</aop:config>

3):配置具体通知的起效位置(即把切入点配置给具体的通知)

<bean id="aspectBean" class="路径">
。。。
</bean>
<aop:config>
<aop:aspect id="myAspect" ref="aspectBean">
<aop:pointcut expression="execution(返回值 路径.方法名(参数列表))" id="pointcut_1"/>//配置一个切入点 <aop:通知类型 method="切面bean类中的一个通知名" pointcut-ref="point_id" />//法一:用已经定义的切入点来配置
<aop:通知类型 method="切面bean类中的一个通知名" pointcut="execution(返回值 路径.方法名(参数列表))" />//法二:自定义一个只用一次的切入点来配置 。。。
</aop:aspect>
</aop:config>

  通知类型指定了被配置的通知方法在切入点起效的时机:切入点前?后?或者前后都执行?还是抛出异常后才执行?主要有以下几种:

(1)aop:around :自定义在切入点方法执行前、后的操作,这个通知方法的定义有一定的格式:参数列表第一个参数必须是切入点

public Object around_advice(ProceedingJoinPoint point,......)//把切入点传进来,其他参数照常传
{
Object res=null;
try{
自定义切入点执行前的操作;
point.proceed();//执行切入点方法
自定义切入点执行后的操作;
}catch(Throwable e){
....
}
return res;
}

(2)aop:before:JointPoint前执行通知

(3)aop:after-returning:JointPoint方法执行完毕,正常返回值并退出方法后,执行该通知

(4)aop:after:切入点方法代码执行完最后一行后,执行该通知。它与after-returning不同,它无论切入点是否正常退出,都会执行。所以也叫finally advice。

(5)aop:after-throwing:JointPoint抛出异常时执行。注意:切入点方法抛出异常后,则不是正常返回退出,所以此时after-returning通知是不会执行的。这种通知可以通过throwing属性指定抛出什么异常时执行通知。

(6)aop:introduction:JointPoint调用完毕后

4)配置Introductions

SpringAOP中的引入是通过“新增父类”的形式来实现的,所用标签是 <aop:declare-parents>。考虑到扩展性,这里还用到了面向接口编程的原则,为匹配的类新增的父类是某个接口的实现类。也就是说:引入,不仅为匹配类新增了父类,还新增了被实现的接口,因此可以用接口来接收getBean的对象,然后调用新增的方法

首先:定义要引入的父类接口以及接口实现类

package com.ygj;

interface Person{//父类接口:定义了要引入通知对象的新增方法
void driveCar();
} class Father implements Person{//接口实现类:实现了新增方法
public void driveCar(){
System.out.println("开车去玩");
}
}

然后,在切面中进行配置,通过正则表达式匹配要增强的目标类,为它们定义上述父类接口以及实现类:

<aop:config>
<aop:aspect id="myAspect" ref="aspectBean">
<aop:declare-parents
types-matching="要增强的类的路径,可用正则表达式匹配多个类,如:com.people.Son"
implement-interface="引入的父类接口完整路径,如:com.ygj.Person"
default-impl="接口的实现类,如:com.ygj.Father"/>
。。。
</aop:aspect>
</aop:config>

最后,可以用引入的父接口去获取被增强的类对象,并且可以调用引入的方法了:

Person person=(Person)applicationContext.getBean("Son");//面向接口编程
person.driveCar();//调用引入的方法

5)Advisors

与事务管理advice配合使用,见下一篇博文。

Spring学习笔记四:SpringAOP的使用的更多相关文章

  1. 1.3(Spring学习笔记)Spring-AOP

    一.AOP简介 AOP面向切面编程,是将一种横向抽取机制,将多个类中需要使用的方法提取出来. 例如,这里有两个类,一个Cat,一个Dog,动物都需要吃饭睡觉,如果按照传统的思想. 给两类中都添加吃饭和 ...

  2. Spring学习笔记四 整合SSH

    三大框架架构(整合原理) 步骤1:导包 Hibernate包 1.Hibernate包,hibernate/lib/required 2.hibernate/lib/jpa | java persis ...

  3. spring学习笔记四:AOP

    AOP(Aspect Orient Programming),面向切面编程,是对面向对象编程OOP的一种补充 面向对象编程使用静态角度考虑程序的结构,而面向切面编程是从动态角度考虑程序运行过程 AOP ...

  4. spring学习笔记四:spring常用注解总结

    使用spring的注解,需要在配置文件中配置组件扫描器,用于在指定的包中扫描注解 <context:component-scan base-package="xxx.xxx.xxx.x ...

  5. Spring学习笔记(六)—— SSH整合

    一.整合原理 二.整合步骤 2.1 导包 [hibernate] hibernate/lib/required hibernate/lib/jpa 数据库驱动 [struts2] struts-bla ...

  6. spring学习笔记(一) Spring概述

    博主Spring学习笔记整理大部分内容来自Spring实战(第四版)这本书.  强烈建议新手购入或者需要电子书的留言. 在学习Spring之前,我们要了解这么几个问题:什么是Spring?Spring ...

  7. Java框架spring 学习笔记(十八):事务管理(xml配置文件管理)

    在Java框架spring 学习笔记(十八):事务操作中,有一个问题: package cn.service; import cn.dao.OrderDao; public class OrderSe ...

  8. 不错的Spring学习笔记(转)

    Spring学习笔记(1)----简单的实例 ---------------------------------   首先需要准备Spring包,可从官方网站上下载.   下载解压后,必须的两个包是s ...

  9. Java架构师之路 Spring学习笔记(一) Spring介绍

    前言 这是一篇原创的Spring学习笔记.主要记录我学习Spring4.0的过程.本人有四年的Java Web开发经验,最近在面试中遇到面试官总会问一些简单但我不会的Java问题,让我觉得有必要重新审 ...

随机推荐

  1. mysql 查询时间戳(TIMESTAMP)转成常用可读时间格式

    from_unixtime()是MySQL里的时间函数 date为需要处理的参数(该参数是Unix 时间戳),可以是字段名,也可以直接是Unix 时间戳字符串 后面的 '%Y%m%d' 主要是将返回值 ...

  2. 《学习R》

    <学习R> 基本信息 原书名:Learning R 原出版社: O'Reilly Media 作者: (美)Richard Cotton 译者: 刘军 丛书名: 图灵程序设计丛书 出版社: ...

  3. 配置SSD-caffe测试时出现“Check failed: error == cudaSuccess (10 vs. 0) invalid device ordinal”解决方案

    这是由于GPU数量不匹配造成的,如果训练自己的数据,那么我们只需要将solver.prototxt文件中的device_id项改为自己的GPU块数,一块就是0,两块就是1,以此类推. 但是SSD配置时 ...

  4. Chrome浏览器导出pdf时,隐藏链接HREF

    在使用chrome打印pdf是,会出现链接的HREF也同时打印的情况,只要加一句CSS即可 @media print {   a[href]:after {     content: none !im ...

  5. ASP.NET C#根据HTML页面导出PDF

    在启明星采购系统里,新增了导出PDF功能.整个功能使用了第三方软件 wkhtmltopdf(下载) 官网 https://wkhtmltopdf.org/ 提供有更多版本下载 他可以把HTML页面转换 ...

  6. J2ee高并发情况下监听器

    引言:在高并发下限制最大并发次数,在web.xml中用过滤器设置參数(最大并发数),并设置其它相关參数.具体见代码. 第一步:配置web.xml配置,不懂的地方解释一下:參数50通过參数名maxCon ...

  7. 从客户端(ctl00$ContentPlaceHolder1$result="<?xml version="1.0" ...")中检测到有潜在危险的 Request.Form 值。

    ylbtech-Error-WebForm:从客户端(ctl00$ContentPlaceHolder1$result="<?xml version="1.0" . ...

  8. [leetcode]Sort Colors @ Python

    原题地址:https://oj.leetcode.com/problems/sort-colors/ 题意: Given an array with n objects colored red, wh ...

  9. C# MemCached分布式缓存

    using System; using System.Collections.Generic; using System.Text; using Memcached.ClientLibrary; us ...

  10. js改变iframe 的src地址

    <script> function dizhi(){ document.getElementById("aaa").src='http://www.sohu.com' ...