Spring框架学习第四讲(AOP原理——XML实现)

一、AOP原理

1.1 AOP概念

  1. AOP:面向切面(方面)编程,扩展功能时,不需要修改源代码,只需要修改配置文件就可以了;
  2. AOP:采取横向抽取机制,取代了传统的纵向继承体系重复性代码;

1.2 AOP原理发展过程

  1. 纵向抽取机制原理

《Spring框架学习第四讲(AOP原理——XML实现)》
2. 横向抽取机制:使用动态代理方式实现

《Spring框架学习第四讲(AOP原理——XML实现)》

《Spring框架学习第四讲(AOP原理——XML实现)》

1.3 AOP操作术语

  1. 连接点(join point):类里面哪些方法可以增强,这些方法就称为连接点;
  2. 切入点(pointcut):在类里面有很多的方法可以被增强,比如实际操作中,只是增强了类里面的某一个方法,则实际增强的方法就称为点。
  3. 通知/增强(advice):增强的逻辑,称为增强,比如扩展日志功能,,这个日志功能就称为增强。有5种类型的通知:
    • 前置通知(Before):在方法被调用之前执行;
    • 后置通知(After):在方法被调用之后执行,不管被通知的方法是否执行成功;
    • 返回通知(After-Returning):在方法成功执行之后执行;
    • 异常通知(After-Throwing):在方法抛出异常后执行;
    • 环绕通知(Around):通知包裹了被通知的方法,即在被通知的方法调用之前和之后都执行。
  4. 切面(Aspect):把增强应用到具体方法上面的过程就称为切面,即把增强用到切入点的过程。

二、AspectJ切面

  1. 在Spring里面进行AOP操作,主要使用AspectJ实现

    • AspectJ还是Spring一部分,而是和Spring一起使用实现AOP操作;
  2. 使用AspectJ实现AOP有两种方法:

    • 基于AspectJ的XML配置方式;
    • 基于AspectJ的注解方式;

2.1 AOP操作的前期准备

  1. 除了导入Spring的基本JAR包之外,还需要导入与AOP相关的JAR包;
    • aopalliance,aspertjweaver,aop,aspects

Jar包下载链接为:

springframework下载链接:
http://download.csdn.net/detail/u014800380/9766304

  1. 创建Spring核心配置文件,并且导入AOP的约束;
  2. 使用表达式定义切入点,表达式的格式为:

execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)

2.2 常用的表达式:

  • execution(* com.spring.aop.Book.add(..)),定义了一个访问修饰符任意,在com.spring.aop包下Book类add方法的切面;
  • execution(* com.spring.aop.Book.*add(..)),定义了访问修饰符任意,在com.spring.aop包下Book类的任选方法的切面;
  • execution(* .(..)),定义了访问修饰符任意,在任意包下任意类任意方法的切面;
  • execution(* save.*(..)),定义了所有save开头的方法的切面;

2.3 AOP操作实例(使用XML进行配置)

2.3.1 创建被增强类和增强类

被增强类Book

package com.spring.aop;

public class Book {
    public void add(){
        System.out.println("book add...");
    }
}

增强类BookService

package com.spring.aop;

public class BookService {
    public void before(){
        System.out.println("bookService add....");
    }
}

2.3.2 创建aopBean.xml配置文件,并添加AOP约束

<?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 definitions here -->
</bean>

2.3.3 在XML配置文件中装配bean和AOP

其中切入点为Book类中的任意方法,切入点id=”pointcut1”;切面为BookService类中的before方法。

<!-- 第一步 配置对象 -->
    <bean id="book" class="com.spring.aop.Book"></bean>
    <bean id="bookService" class="com.spring.aop.BookService"></bean>

    <!-- 第二步 配置AOP操作 -->
    <aop:config>
        <!-- 2.1 配置切入点 -->
        <aop:pointcut expression="execution(* com.spring.aop.Book.*(..))" id="pointcut1"/>

        <!-- 2.2 配置切面:把通知用到方法上 -->
        <aop:aspect ref="bookService">
            <!-- 配置增强类型 method:增强类里面使用哪个方法作为前置 -->
            <aop:before method="before" pointcut-ref="pointcut1"/>

        </aop:aspect>
    </aop:config>

2.3.4 写测试代码

public class aopTest {
    @Test
    public void testBook(){
        ApplicationContext context = new ClassPathXmlApplicationContext("aopBean.xml");
        Book book = (Book) context.getBean("book");
        book.add();
        book.print();
    }
}

2.3.5 输出结果

bookService add....
book add...

2.4 AOP的其他操作

2.4.1 修改增强类BookService

需要注意的是环绕方法,需要引入一个ProceedingJoinPoint对象!

package com.spring.aop;

import org.aspectj.lang.ProceedingJoinPoint;

public class BookService {
    public void before1(){
        System.out.println("bookService before....");
    }

    public void after1(){
        System.out.println("bookService after.....");
    }

    public void around1(ProceedingJoinPoint jp) throws Throwable{
        System.out.println("around before..");
        //执行被增强的方法
        jp.proceed();

        System.out.println("around after..");
    }
}

2.4.2 修改配置文件aopBean.xml

<!-- 第一步 配置对象 -->
    <bean id="book" class="com.spring.aop.Book"></bean>
    <bean id="bookService" class="com.spring.aop.BookService"></bean>

    <!-- 第二步 配置AOP操作 -->
    <aop:config>
        <!-- 2.1 配置切入点 -->
        <aop:pointcut expression="execution(* com.spring.aop.Book.*(..))" id="pointcut1"/>

        <!-- 2.2 配置切面:把通知用到方法上 -->
        <aop:aspect ref="bookService">
            <!-- 配置增强类型 method:增强类里面使用哪个方法作为前置 -->
            <aop:before method="before1" pointcut-ref="pointcut1"/>

            <!-- 后置方法 -->
            <aop:after method="after1" pointcut-ref="pointcut1"/>

            <!-- 环绕通知方法 -->
            <aop:around method="around1" pointcut-ref="pointcut1"/>
        </aop:aspect>
    </aop:config>

2.4.2 测试代码不变,输出结果

bookService before....
around before..
book add...
around after..
bookService after.....
    原文作者:AOP
    原文地址: https://blog.csdn.net/u014800380/article/details/59113960
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞