欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

3. Spring AOP 介绍

程序员文章站 2022-07-12 16:43:01
...

aop 概念

  • aop 面向切面 编程
  • aop 采用横向抽取机制,取代了传统的纵向继承体系重复性代码

aop 底层原理

  • 纵向机制
    3. Spring AOP 介绍
  • 横向机制
    3. Spring AOP 介绍
    3. Spring AOP 介绍

aop 操作 术语

Joinpoint 连接点

指那些被拦截到的点.在Spring中,这些点指的是方法,因为Spring只支持方法类型的连接点

Pointcut 切入点

是指我们要对哪些Joinpoint进行拦截的定义

Advice 通知/增强

是指拦截到Joinpoint之后所要做的事情就是通知,通知分为前置通知/后置通知/异常通知/最终通知/环绕通知(切面要完成的功能)
* 前置通知before
* 后置通知aop:after
* 异常通知aop:after-throwing
* 最终通知aop:after-returning
* 环绕通知aop:around

Aspect 切面

是切入点和通知(引介)的结合

Introduction 引介

是一种特殊的通知在不修改类代码的前提下,Introduction可以在运行期为类动态的添加一些方法或field.

Target 目标对象

代理的目标对象(要增强的类)

Weaving 织入

把advice应用到target的过程

Proxy 代理

一个类被aop织入增强后,就产生了一个结果代理类


Spring 的 aop 操作

  • 在Spring使用aop,用到了AspectJ的框架
  • AspectJ是一个专门处理AOP操作的框架

aspectJ实现aop

  1. 需要添加新的jar包
    • spring-aop
    • spring-aspectj
    • aopalliance
    • aspectjweaver
  2. aop的约束
<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">

使用表达式配置切入点

常用表达式:execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)
* 写法
1. execution(* com.bean.User.show(..))
- 指定方法
2. execution(* com.bean.User.*(..))
- 指定类中的所有方法
3. execution(* *.*(..))
- 指定所有类的所有方法
4. execution(* show*(..))
指定所有show开头的方法

xml

实体类

package com.bena;

public class Student {
    private int sid;
    private String sname;
    /**执行的方法*/
    public void print (){
        System.out.println("Student [sid=" + sid + ", sname=" + sname + ", sex=" + sex + "]\n");
    }
..set\get方法...
}

增强方法

package com.test;

import org.aspectj.lang.ProceedingJoinPoint;

public class advisor {
    public void before() {
        System.out.println("方法之前");
    }

    public void after() {
        System.out.println("方法之后");
    }

    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("环绕>方法之前");
        proceedingJoinPoint.proceed();
        System.out.println("环绕>方法之后");
    }
}

xml配置

<?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 id="st1" class="com.bena.Student">
        <property name="sid" value="1" />
        <property name="sname" value="leiming" />
        <property name="sex" value="men" />
    </bean>
    <!-- 1.配置切面对象 -->
    <bean id="advisor1" class="com.test.advisor"/>
    <!-- 2.配置aop -->
    <aop:config>
        <!-- 2.1配置切入点 -->
        <aop:pointcut expression="execution(* com.bena.*.*(..))"
            id="pointcut1" />
        <!-- 2.2配置切面 把增强用到方法上面 -->
        <aop:aspect ref="advisor1">
            <!-- 配置增强类型 
                 method:增强类里面使用的那个方法前面 
                 pointcut-ref:引用的切点
            -->
            <!-- 执行方法之前 -->
            <aop:before method="before" pointcut-ref="pointcut1" />
            <!-- 执行方法之后 -->
            <aop:after method="after" pointcut-ref="pointcut1"/>
            <!-- 环绕执行方法 -->
            <aop:around method="around" pointcut-ref="pointcut1"/>
        </aop:aspect>
    </aop:config>
</beans>

执行方法

public class Test {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Student st = (Student) context.getBean("st1");
        st.print();
    }
}

执行结果

方法之前
环绕>方法之前
Student [sid=1, sname=leiming, sex=men]
环绕>方法之后
方法之后

注解


aop 标签

  • <aop:config> aop配置根
    • <aop:pointcut>创建切点
      • expression方法表达式
      • id唯一名称
    • <aop:aspect>创建增强方法
      • ref 引用增强类(由bean 标签创建)
      • 前置增强<aop:before>
      • 后置增强<aop:after>
      • 异常增强<aop:after-throwing>
      • 最终增强<aop:after-returning>
      • 环绕增强<aop:around
        • 引用对象的方法名method="ref引用对象的方法名"
        • 传入方法的参数arg-names由逗号分隔的通知方法参数(参数)名称列表,这些名称将与切入点参数匹配。
        • 切入点 pointcut相关的切入点表达式。
        • 切入点引用pointcut-ref关联切入点定义的名称(由bean 标签创建)
    • <aop:advisor>创建增强事务专用
      • 通知引用advice-ref(由bean 标签创建)
      • 切入点 pointcut相关的切入点表达式。
      • 切入点引用pointcut-ref关联切入点定义的名称(由bean 标签创建)