Spring AOP(Aspect Oriented Programming)面向切面编程(配置方式)

AOP和继承的区别

继承是横向的,当父类名称更改的时候,子类方法里面也需要更改
aop是横向的,通过创建动态代理对象(不是真正的对象,但是可以实现功能)来实现

AOP原理

在这里插入图片描述
底层都是是用动态代理实现,不修改源代码,只是增强功能。


AOP操作术语

public class User {
    public void add() { }
    public void update() { }
    public void delete() { }
    public void findAll() { }
}

Joinpoint(连接点)

类里面的哪些方法可以被增强,这些方法就叫做连接点,例如上面的这些方法都可以作为接入点。

Pointcut(切入点)

在类里面有很多方法可以被增强,但是在实际中,被增强的方法叫做切入点
比如add方法和update方法被增强。

Advice(通知/增强)

实际增强的逻辑,比如扩展日志的功能,那么这个日志功能就叫做增强
增强/通知分为:

  1. 前置通知:在方法之前执行
  2. 后置通知:在方法之后执行
  3. 异常通知:方法出现异常执行
  4. 最终通知:后置之后执行finally
  5. 环绕通知:方法之前和之后都会执行,例如计算方法时间

Aspect(切面)

增强应用到具体切入点的过程
比如在日志功能用在add方法上面过程

Introduction(引介)

动态添加属性或者方法,一般不用

Target(目标对象)

需要增强的对象(User)

Weaving(织入)

把advice应用到target的过程

Proxy(代理)

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


Spring里AOP的操作

Spring里面使用AspectJ来实现AOP操作
AspectJ是一个单独的AOP框架,本身不是Spring的一部分
Spring2.0之后,增加对AspectJ的支持

使用AcpectJ有两种操作:

  1. 基于xml方式
  2. 基于注解的方式

AOP准备工作

  1. 导入AOP相关的jar包
  2. 在核心配置文件导入AOP的约束

配置文件的方式实现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:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd
           http://www.springframework.org/schema/aop            
           http://www.springframework.org/schema/aop/spring-aop-3.1.xsd  
           "><!-- 要添加最后2行 -->

下载aspectj的jar包:
https://www.eclipse.org/aspectj/downloads.php

在这里插入图片描述
有两个对象:

public class Book {
    public void add() {
        System.out.println("add......");
    }
}
public class MyBook {
    public void before() {
        System.out.println("前置增强");
    }
}

我们想要在执行Book的add方法之前,先执行MyBook的before方法。
传统的方式是需要在代码里面创建新的对象。

表达式配置切入点:

在这里插入图片描述

execution(* aop.Book.add(..))

前面使用*表示任意访问修饰符 后面接方法名的全路径

第二种写法:

execution(* aop.Book.*(..))

表示对类里面的所有方法增强
第三种写法:

execution(* *.*(..))

所有的方法

AspectJ的AOP操作

首先需要配置对象。

<bean id="book" class="aop.Book"></bean>
<bean id="myBook" class="aop.MyBook"></bean>

配置AOP的操作

  1. 配置切入点(使用表达式的方式表示对哪个类进行增强)
  2. 配置切面(把增强用在方法上)
    <aop:config>
        <!--配置切入点-->
        <aop:pointcut id="addPointCut" expression="execution(* aop.Book.*(..))"/>
        <!--配置切面-->
        <aop:aspect ref="myBook">
            <!--配置增强类型-->
            
        </aop:aspect>

    </aop:config>

可以看到有很多种增强类型。
在这里插入图片描述

<aop:config>
        <!--配置切入点-->
        <aop:pointcut id="addPointCut" expression="execution(* aop.Book.*(..))"/>
        <!--配置切面-->
        <aop:aspect ref="myBook">
            <!--配置增强类型-->
            <aop:before method="before" pointcut-ref="addPointCut"></aop:before>
        </aop:aspect>
    </aop:config>

这里,如果报错,是因为没有导入这个包在这里插入图片描述
添加方式:
在这里插入图片描述
在这里插入图片描述

编程测试
public class MyTest {
    @Test
    public void testAop() {
        ApplicationContext context =
                new ClassPathXmlApplicationContext("bean3.xml");
        Book book = (Book) context.getBean("book");
        System.out.println(book);
        book.add();
    }

}

在这里插入图片描述
由测试结果可以看到,add方法作为切入点,已经被前置增强了

后置增强
<aop:config>
            <!--配置切入点-->
            <aop:pointcut id="addPointCut" expression="execution(* aop.Book.*(..))"/>
            <!--配置切面-->
            <aop:aspect ref="myBook">
                <!--配置增强类型-->
                <aop:before method="before" pointcut-ref="addPointCut"/>
                <aop:after-returning method="after" pointcut-ref="addPointCut"/>
            </aop:aspect>

        </aop:config>

上面这个地方,用aop:after也是可以的。。。
在这里插入图片描述

环绕通知

增强代码

public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        //方法之前
        System.out.println("方法之前");

        //执行被增强的方法
        proceedingJoinPoint.proceed();

        //方法之后
        System.out.println("方法之后");
    }

配置增强

<aop:config>
            <!--配置切入点-->
            <aop:pointcut id="addPointCut" expression="execution(* aop.Book.*(..))"/>
            <!--配置切面-->
            <aop:aspect ref="myBook">
                <!--配置增强类型-->
                <aop:before method="before" pointcut-ref="addPointCut"/>
                <aop:after-returning method="after" pointcut-ref="addPointCut"/>
                <aop:around method="around" pointcut-ref="addPointCut"/>
            </aop:aspect>

        </aop:config>

在这里插入图片描述
在方法之前和之后做同样操作
但是在before之后
after之前

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值