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.结果