一、相关概念
切入点表达式:指配置对哪个类的哪个方法进行增强的表达式。
格式:execution(表达式)
具体格式举例:
execution(public void com.yooyo.service.impl.AccountServiceImpl.findAll())
表示对修饰符为public返回值为void的com.yooyo.service.impl包下AccountServiceImpl类的无参方法findAll()进行增强
通配符格式举例:
execution(* com.yooyo.service.*.*ServiceImpl.findAll(…))
表示对任意返回值的com.yooyo.service.*包下的以ServiceImpl结尾的类的任意参数的findAll()
进行增强,其中修饰符省略 ,参数列表 …表示任何类型和个数
前置通知:在切入点方法之前执行
返回成功通知:在切入点方法执行成功之后执行
返回异常通知:在切入点方法抛出异常后执行
最终通知:不管切入点方法执行成功还是抛出异常都会执行
环绕通知:在切入点方法执行前后都可以执行,
需要在增强方法参数引入ProceedingJoinPoint,然后在增强方法中ProceedingJoinPoint.proceed()方法控制切入点方法的执行
二、具体实现
1.环境搭建
在已有环境及Demo上扩展,地址如下
https://blog.youkuaiyun.com/qqq327954699/article/details/85228003
2.创建切面类src/main/java/com.yooyo.aop/LogXmlAspect.java
package com.yooyo.aop;
import org.aspectj.lang.ProceedingJoinPoint;
public class LogXmlAspect {
/**
* 最终通知测试
* @param jp
*/
public void logAround(ProceedingJoinPoint jp) {
try {
System.out.println("环绕通知前置...");
Object proceed = jp.proceed();
System.out.println(proceed);
System.out.println("环绕通知返回成功...");
} catch (Throwable e) {
System.out.println("环绕通知抛出异常...");
e.printStackTrace();
}finally {
System.out.println("环绕通知最终...");
}
}
/**
* 其他通知测试
*/
public void log() {
System.out.println("aop输出日志...");
}
}
3.在spring配置文件,配置切面类、增强
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p" 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" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:component-scan base-package="com.yooyo">
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<!-- 加载配置文件 -->
<context:property-placeholder location="classpath:config/jdbcConfig.properties" />
<!-- 配置MyBatis的Session工厂 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 数据库连接池 -->
<property name="dataSource" ref="dataSource" />
<!-- 加载mybatis的全局配置文件 -->
<property name="configLocation" value="classpath:mybatis/SqlMapConfig.xml" />
</bean>
<!-- 配置数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="user" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.yooyo.dao" />
</bean>
<!-- 配置切面类 -->
<bean id="logXmlAspect" class="com.yooyo.aop.LogXmlAspect"/>
<!-- 配置aop增强 -->
<aop:config>
<!-- 配置公共的切入点表达式 -->
<aop:pointcut expression="execution(* com.yooyo.service.*.*ServiceImpl.findAll(..))" id="pc"/>
<!-- 配置切面 = 通知(增强类的某个增强方法) + 切入点表达式(对哪个类的哪个方法进行增强) -->
<aop:aspect ref="logXmlAspect">
<aop:before method="log" pointcut-ref="pc" />
<!--
前置通知,在切入点方法之前执行
<aop:before method="log" pointcut="execution(* com.yooyo.service.*.*ServiceImpl.findAll(..))"/>
-->
<!--
返回成功通知,在切入点方法执行成功之后执行
<aop:after-returning method="log" pointcut="execution(* com.yooyo.service.*.*ServiceImpl.findAll(..))"/>
-->
<!--
返回异常通知,在切入点方法抛出异常后执行
<aop:after-throwing method="log" pointcut="execution(* com.yooyo.service.*.*ServiceImpl.findAll(..))"/>
-->
<!--
最终通知,不管切入点方法执行成功还是抛出异常都会执行
<aop:after method="log" pointcut="execution(* com.yooyo.service.*.*ServiceImpl.findAll(..))"/>
-->
<!--
环绕通知,在切入点方法执行前后都可以执行,需要在增强方法参数引入ProceedingJoinPoint,
然后在增强方法中ProceedingJoinPoint.proceed()方法控制切入点方法的执行
<aop:around method="logAround" pointcut="execution(* com.yooyo.service.*.*ServiceImpl.findAll(..))"/>
-->
</aop:aspect>
</aop:config>
</beans>