一篇文章帮你搞定 Spring 基于XML的AOP配置

一、需求

模拟一个账户实现类,要求,在业务层实现类之前,需要执行打印日志,即相当于公共的代码

/**
 * 账户的业务层实现类
 */
public class AccountServiceImpl implements AccountService {

    @Override
    public void saveAccount() {
        System.out.println("执行了保存");
    }

    @Override
    public void updateAccount(int i) {
        System.out.println("执行了更新"+i);

    }

    @Override
    public int deleteAccount() {
        System.out.println("执行了删除");
        return 0;
    }
}
/**
 * 用于记录日志的工具类,它里面提供了公共的代码
 */
public class Logger {

    /**
     * 用于打印日志:计划让其在切入点方法执行之前执行(切入点方法就是业务层方法)
     */
    public  void printLog(){
        System.out.println("Logger类中的pringLog方法开始记录日志了。。。");
    }
}

二、基于XML的AOP配置步骤

(1)把通知 Bean 也交给spring来管理:这里就是将logger添加到spring容器中

 <!-- 配置Logger类 -->
    <bean id="logger" class="spring.utils.Logger"></bean>

(2)使用aop:config标签表明开始AOP的配置

<aop:config>
<!-- 配置的代码都写在此处 -->
</aop:config>

(3)使用aop:aspect标签表明配置切面

  	* id属性:是给切面提供一个唯一标识
 	* ref属性:是指定通知类bean的Id。

<aop:aspect id="logAdvice" ref="logger">
            <!--配置切入点的表达式-->
            <aop:pointcut id="pt" expression="execution(* spring.service.impl.*.*(..))"/>
            <!-- 配置通知的类型,并且建立通知方法和切入点方法的关联-->
            <aop:before method="printLog" pointcut-ref="pt"></aop:before>
</aop:aspect>

(4)在使用 aop:pointcut 配置切入点表达式

aop:pointcut:
作用:用于配置切入点表达式。就是指定对哪些类的哪些方法进行增强。
属性:
	* expression:用于定义切入点表达式。
	* id: 用于给切入点表达式提供一个唯一标识

<!--配置切入点的表达式-->
<aop:pointcut id="pt" expression="execution(* spring.service.impl.*.*(..))"/>

此标签写在aop:aspect标签内部只能当前切面使用。它还可以写在aop:aspect外面,此时就变成了所有切面可用
在这里插入图片描述
(5)使用 aop:xxx 配置对应的通知类型

我们现在示例是让printLog方法在切入点方法执行之前之前:所以是前置通知
    * method:用于指定通知类中的增强方法名称
	* ponitcut-ref:用于指定切入点的表达式的引用
	* poinitcut:用于指定切入点表达式 

作用相同:不同的表达方式:

 <!-- 配置通知的类型,并且建立通知方法和切入点方法的关联-->
<aop:before method="printLog" pointcut-ref="pt"></aop:before>
<aop:before method="printLog" pointcut="execution(* spring.service.impl.*.*(..))"></aop:before>

在这里插入图片描述

三、切入点表达式说明

execution:匹配方法的执行(常用)
execution(表达式)表达式语法: execution([修饰符] 返回值类型 包名.类名.方法名(参数))

写法说明:
全匹配方式:public void spring.service.impl.AccountServiceImpl.saveAccount()

(1)访问修饰符可以省略void spring.service.impl.AccountServiceImpl.saveAccount()
(2)返回值可以使用通配符,表示任意返回值* spring.service.impl.AccountServiceImpl.saveAccount()
(3)包名可以使用通配符,表示任意包。但是有几级包,就需要写几个*.

* *.*.*.AccountServiceImpl.saveAccount())

(4)包名可以使用..表示当前包及其子包

* *..AccountServiceImpl.saveAccount())

(5)类名和方法名都可以使用*来实现通配 * *..*.*()

参数列表,可以直接写数据类型:
           基本类型直接写名称           int
           引用类型写包名.类名的方式   java.lang.String
           可以使用通配符表示任意类型,但是必须有参数
           可以使用..表示有无参数均可,有参数可以是任意类型

(6)全通配写法: * *..*.*(..)

(7)实际开发中切入点表达式的通常写法:切到业务层实现类下的所有方法

 * spring.service.impl.*.*(..)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南淮北安

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值