使用Spring-AOP

在开始使用Spring的AOP之前我们需要在bean.xml中引入aop约束,并在pom.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">
        <!--........-->
</beans>
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.0.2.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.8.7</version>
    </dependency>
</dependencies>

一、编写公共代码制作成通知

package com.itheima.utils

/**
 * 用于记录日志的工具类,它里面提供了公共的代码
 */
public class Logger {

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

二、编写配置文件

1.把通知类用bean标签配置起来

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

2.使用aop:config申明aop配置

<!--配置AOP-->
<aop:config>
	<!--配置代码-->
</aop:config>

3.使用aop:aspect配置切面

 <!--配置AOP-->
 <aop:config>
     <!--配置切面 -->
     <aop:aspect id="logAdvice" ref="logger">
        <!--配置通知类型-->
     </aop:aspect>
 </aop:config>

4.使用aop:pointcut配置切入点(要增强的方法)表达式

<!--配置AOP-->
<aop:config>
	<aop:pointcut pointcut="execution(* com.itheima.service.impl.*.*(..))" id="pt1">
    <!--配置切面 -->
    <aop:aspect id="logAdvice" ref="logger">
   		<!--配置通知类型-->
    </aop:aspect>
</aop:config>

切入点表达式的写法:
关键字:execution(表达式)
表达式:访问修饰符 返回值 包名.包名.包名…类名.方法名(参数列表)

标准的表达式写法:public void com.itheima.service.impl.AccountServiceImpl.saveAccount()
访问修饰符可以省略:void com.itheima.service.impl.AccountServiceImpl.saveAccount()

返回值可以使用通配符,表示任意返回值
* com.itheima.service.impl.AccountServiceImpl.saveAccount()

包名可以使用通配符,表示任意包。但是有几级包,就需要写几个*.
* *.*.*.*.AccountServiceImpl.saveAccount())

包名可以使用…表示当前包及其子包
* *…AccountServiceImpl.saveAccount()

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

参数列表:

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

实际开发中切入点表达式的通常写法:
切到业务层实现类下的所有方法:* com.itheima.service.impl.*.*(…)

5.使用aop:xxx配置对应的通知类型

<!--配置AOP-->
<aop:config>
	<!--务必写在配置切面之前,这是spring规定好的-->
	<aop:pointcut expression="execution(* com.itheima.service.impl.*.*(..))" id="pt1"></aop:pointcut>
    <!--配置切面 -->
    <aop:aspect id="logAdvice" ref="logger">	
    	<aop:before method="printLog" pointcut-ref="pt1"></aop:before>
    	<!--aop:pointcut和aop:before也可以合为一句,不过在对一个切入点配置多个aop:xxx的时候,分开写的优势就体现了,即不用多次写切入点表达式-->
    	<!--
    	<aop:before method="printLog" pointcut="execution(* com.itheima.service.impl.*.*(..))"></aop:before>
    	-->
    </aop:aspect>
</aop:config>

aop:xxx:
aop:before
作用:用于配置前置通知

aop:after-returning
作用:用于配置后置通知

aop:after-throwing
作用:配置异常通知

aop:after
配置最终通知

以上这些可以类比java的try-catch执行机制来理解。

三、环绕通知

环绕通知的通知类写法和上面不同,但是在xml中的配置还是差不多的,使用aop:around配置对应的通知类型。环绕通知可以手动控制增强代码什么时候执行,而不限于上面的前置、后置。通常情况下around都是单独使用的,也就是对要增强的方法不用再配置前置、后置之类的通知了。

spring 框架为我们提供了一个接口:ProceedingJoinPoint,它可以作为环绕通知的方法参数。在环绕通知执行时,spring框架会为我们提供该接口的实现类对象,我们直接使用就行。例如对上面的例子进行改写:

package com.chester.utils;

import org.aspectj.lang.ProceedingJoinPoint;
/**
 * 用于记录日志的工具类,它里面提供了公共的代码
 */
public class Logger {

    /**
     * 用于打印日志:计划让其在切入点方法执行之前执行(切入点方法就是业务层方法)
     */
    public void printLog(ProcessingJoinPoint pjp){
	    try{
	        System.out.println("Logger类中的pringLog方法开始记录日志了。。。");
	        pjp.proceed();
	        System.out.println("Logger类中的pringLog方法结束记录日志了。。。");
		}catch(Throwable e){
			System.out.println("运行出错");
			e.printStackTrace();
		}finally{
			 System.out.println("Logger类中的pringLog方法完成记录日志了。。。");
		}
    }
}

现在在xml进行配置:

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

<aop:config>
    <aop:pointcut expression="execution(* com.chester.service.impl.*.*(..))" id="pt1"></aop:pointcut>
    <!--配置切面 -->
    <aop:aspect id="logAdvice" ref="logger">
        <aop:around method="printLog" pointcut-ref="pt1"></aop:around>
    </aop:aspect>
</aop:config>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值