1.首先导入依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.itheima</groupId>
<artifactId>day03_eesy_04adviceType</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>

<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>

</project>

2.创建IAccountService接口和实现类AccountServiceImpl

package com.service;

/**
* 账户业务层的接口
*/
public interface IAccountService {
public void saveAccount() ;

}
package com.service.impl;

import com.service.IAccountService;

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


public void saveAccount() {
System.out.println("执行了保存");
int i=1/0;
}
}

3.创建Logger类测试通知

package com.utils;

public class Logger {
/**
* 前置通知
*/
public void beforePrintLog(){
System.out.println("前置通知Logger类中的beforePrintLog方法开始记录日志了。。。");
}

/**
* 后置通知
*/
public void afterReturningPrintLog(){
System.out.println("后置通知Logger类中的afterReturningPrintLog方法开始记录日志了。。。");
}
/**
* 异常通知
*/
public void afterThrowingPrintLog(){
System.out.println("异常通知Logger类中的afterThrowingPrintLog方法开始记录日志了。。。");
}

/**
* 最终通知
*/
public void afterPrintLog(){
System.out.println("最终通知Logger类中的afterPrintLog方法开始记录日志了。。。");
}

}

4.bean.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">

<!--配置spring的ioc,把service对象配置进来-->
<bean id="accountService" class="com.service.impl.AccountServiceImpl"></bean>
<!--配置logger类-->
<bean id="logger" class="com.utils.Logger"></bean>
<!--配置AOP-->
<aop:config>
<!-- 配置切入点表达式 id属性用于指定表达式的唯一标识。expression属性用于指定表达式内容
此标签写在aop:aspect标签内部只能当前切面使用。
它还可以写在aop:aspect外面,此时就变成了所有切面可用
-->
<aop:pointcut id="pt1" expression="execution(* com.service.impl.*.*(..))"></aop:pointcut>
<!--配置切面-->
<aop:aspect id="logAdvice" ref="logger">
<!--配置通知的类型,并且建立通知方法和切入点方法的关联-->
<aop:before method="beforePrintLog" pointcut-ref="pt1"></aop:before>
<aop:after-throwing method="afterThrowingPrintLog" pointcut-ref="pt1"></aop:after-throwing>
<aop:after-returning method="afterReturningPrintLog" pointcut-ref="pt1"></aop:after-returning>
<aop:after method="afterReturningPrintLog" pointcut-ref="pt1"></aop:after>
</aop:aspect>

</aop:config>

</beans>

配置AOP

aop:pointcut:
作用:
      用于配置切入点表达式。就是指定对哪些类的哪些方法进行增强。
属性:
     expression:用于定义切入点表达式。
    id: 用于给切入点表达式提供一个唯一标识
注:
     通常情况下,我们都是对业务层的方法进行增强,所以切入点表达式都是切到业务层实现类。
     execution(* com.itheima.service.impl..(…))
通常写法规范如下

* com.itheima.service.impl.*.*(..)

这个表示对业务层那个方法增强十分重要

aop:before
作用:
    用于配置前置通知。 指定增强的方法在切入点方法之前执行
属性:
    method:用于指定通知类中的增强方法名称
    ponitcut-ref:用于指定切入点的表达式的引用
    poinitcut:用于指定切入点表达式
执行时间点:
    切入点方法执行之前执行

aop:after-returning
作用:
    用于配置后置通知
属性:
    method: 指定通知中方法的名称。
    pointct: 定义切入点表达式
    pointcut-ref: 指定切入点表达式的引用
执行时间点:
    切入点方法正常执行之后。它和异常通知只能有一个执行

aop:after-throwing
作用:
    用于配置异常通知
属性:
    method: 指定通知中方法的名称。
    pointct: 定义切入点表达式
    pointcut-ref: 指定切入点表达式的引用
执行时间点:
    切入点方法执行产生异常后执行。它和后置通知只能执行一个

aop:after
作用:
    用于配置最终通知
属性:
    method: 指定通知中方法的名称。
    pointct: 定义切入点表达式
pointcut-ref: 指定切入点表达式的引用
    执行时间点:
    无论切入点方法执行时是否有异常,它都会在其后面执行。

5测试类

import com.service.IAccountService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AOPTest {
public static void main(String[] args) {
//1.获取容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//2.获取对象
IAccountService as = (IAccountService)ac.getBean("accountService");
//3.执行方法
as.saveAccount();
}
}

6.结果

spring基于 XML 的 AOP 的前后置通知,异常通知,最终通知_业务层