[5] Spring中的AOP操作(使用xml 配置文件的方式)

来源:互联网 发布:mac 视频特效 编辑:程序博客网 时间:2024/05/20 03:37

AOP (Aspect Oriented Programing) 面向切面编程

  • AOP 采取横向抽取机制,取代了传统的纵向继承体系重复性代码(性能监视、事务管理、安全检查、缓存)
  • Spring AOP使用纯Java实现,不需要专门的编译过程和类加载器,在运行期通过代理方式向目标类织入增强代码

AOP中的相关术语:

这里写图片描述

1.Joinpoint(连接点): 所谓连接点是指那些被拦截到的点。在spring中这些点指的是方法,因为spring中只支持方法类型的连接点。

大白话 ==> [类里面可以被增强的方法,这些方法被称为连接点]

2.Pointcut(切入点) : 所谓切入点是指我们要对哪些Joinpoint进行拦截的定义

大白话==> [在类里面有很多方法被增强,比如实际操作中,只是增强了其中的某一个或者多个方法,这些被增强的方法被称为切入点]

3.Advice(通知/增强) : 所谓是指拦截到Joinpoint之后要做的事情,就是通知。

大白话 ==> [增强的逻辑被称之为通知,比如增加扩展日志的逻辑]
通知分为:

  • 前置通知 : 所要增强的逻辑在切入点之前执行

  • 后置通知 : 所要增强的逻辑在切入点之后执行

  • 返回通知 : 在切入点正常执行(没有出现异常)之后执行的通知叫做返回通知

  • 异常通知 : 当切入点出现异常时执行

  • 环绕通知 : 在要增强的方法在切入点之前和之后执行

4.Introduction(引介) : 引介是一种特殊类型的通知,在不修改类代码的前提下,Introduction可以在运行期为类动态地添加一些方法或Field

5.Target(目标对象) : 代理目标对象(要进行增强的类)

6.Weaving(织入) : 是把增强应用到目标的过程(把Adavice应用到target的过程)

7.Proxy(代理) : 一个类被AOP织入增强后,就产生一个结果的代理类

8.Aspect(切面) : 是指切入点和通知的引介

大白话==>[把增强应用到具体的方法上面,这个过程被称之为切面]

注:使用大字体标注的几个概念都是在Spring比较频繁使用的。

Spring的AOP操作

1. 在Spring中进行的AOP操作,使用AspecJ来实现

AspecJ: 是一个面向切面的框架,它扩展了Java的语言。AspectJ定义了AOP语法所以它有一个专门的编译器用来生成遵循Java字节码规范的Class文件。Spring2.0以后新增了对AspectJ切点表达式的支持

2. 使用AspectJ实现AOP的两种方式 :

  1. 基于AspectJ的XML配置

  2. 基于AspectJ的注解方式

下面介绍如何通过在Spring中通过配置文件的操作来实现AOP操作:

1.首先导入AOP操作所需的jar包

这里写图片描述

2.引入约束

<?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"></beans>

3.使用表达式进行配置

表达式的格式 :execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)

execution常用表达式的写法:
1.  execution(* com.merpyzf.study03.Student.add(..))   : 此处配置的切入点为Student类下的add方法(需要指定类的全路径)2. execution(* com.merpyzf.study03.Student.*(..))  :此处配置的切入点为Student类中的所有方法3.execution(*,*.*(..)) :此处配置的切入点为所有类中的所有方法

下面来演示一下Spring AOP的一个操作过程 :

下面例子对Student类中的readBook()方法进行了一个增强,下面看代码:

Student.java(被增强类)

/** * Created by 春水碧于天 on 2017/6/25. *///被增强类public class Student {    public void readBook(){        System.out.println("读书中……");        //手动产生异常//        int s = 1/0;    }}

StudentPower.java(增强类)

/** * Created by 春水碧于天 on 2017/6/25. *///增强类public class StudentPower {    public void buyBook(){        System.out.println("我买了一本书 ==> <aop:before>");    }    public void sellBook(){        System.out.println("我要把书卖掉! ==> <aop:after>");    }     public void around(ProceedingJoinPoint proceedingJoinPoint){         System.out.println("开始读书 ==> <aop:around>" );         try {             //调用要增强的方法             proceedingJoinPoint.proceed();         } catch (Throwable throwable) {             throwable.printStackTrace();         }         System.out.println("书读完了==> <aop:around>");     }     public void exp(){         System.out.println("切入点抛出异常了 <aop:after-throwing>");     }     public void afterReturning(){         System.out.println("切入点正常执行没有出现异常 ==> <aop:after-returning>");    }}

applicationContextAop.xml(Spring配置文件)

<?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">    <!--配置进行创建对象-->    <bean id="student" class="com.merpyzf.study03.Student"></bean>    <bean id="studentPower" class="com.merpyzf.study03.StudentPower"></bean>    <!--配置aop操作-->    <aop:config>        <!--配置切入点(需要进行增强的方法 ) 这里需要增强的方法为Student类中的readBook方法-->        <aop:pointcut id="pointcute1" expression="execution(* com.merpyzf.study03.Student.readBook(..))"></aop:pointcut>        <!--配置切面 (把增强应用到具体的方法上面,这个过程被称之为切面)-->        <!--StudentPower为增强的类-->        <aop:aspect ref="studentPower">            <!--将 buyBook 做为前置通知配置到pointcute1 对应的方法为 readBook()-->            <aop:before method="buyBook" pointcut-ref="pointcute1"></aop:before>            <!--将 sellBook 做为后置通知配置到pointcute1 对应的方法为 readBook()-->            <aop:after method="sellBook" pointcut-ref="pointcute1"></aop:after>            <!--将 buyBook 做为环绕配置到pointcute1 对应的方法为 readBook()-->            <aop:around method="around" pointcut-ref="pointcute1"></aop:around>            <!--将 buyBook 做为异常通知配置到pointcute1 对应的方法为 readBook()-->            <aop:after-throwing method="exp" pointcut-ref="pointcute1"></aop:after-throwing>            <!--将 buyBook 做为返回通知配置到pointcute1 对应的方法为 readBook()-->            <aop:after-returning method="afterReturning" pointcut-ref="pointcute1"></aop:after-returning>        </aop:aspect>    </aop:config></beans>

MyTest.java(测试代码)

/** * Created by 春水碧于天 on 2017/6/25. */public class MyTest {    @Test    public void Test(){        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContextAop.xml");        Student student = (Student) context.getBean("student");        student.readBook();    }}

下面看一下运行结果:

这里写图片描述

可以看到增强的方法按照在配置文件中所配置的通知顺序依次成功执行,需要注意的是当切入点没有出现异常的时候 配置为 返回通知(after-returning) 那个增强方法正常执行。下面我们手动制造一个异常再看一下运行的结果:

这里写图片描述

可以看到 配置为 异常通知(after-throwing) 的增强方法被执行了,而 配置为返回通知(after-returning)的那个增强方法并没有被执行。

看到这里相信应该明白每个通知的各自的执行流程了吧。

阅读全文
0 0