1:准备环境
<!--配置解析切入点表达式的jar包-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.7</version>
</dependency>
</dependencies>
2:开始配置
2.1:xml配置文件中添加aop的约束
xmlns:aop="http://www.springframework.org/schema/aop"
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
xsi:schemaLocation中的链接总是成对存在
2.2:配置被代理对象和增强对象
<!--配置被代理对象-->
<bean id="ccountService" class="com.aiitec.service.impl.AccountServiceImpl">
<property name="accountDao" ref="accountDao"></property>
</bean>
<bean id="accountDao" class="com.aiitec.dao.impl.AccountDaoImpl"></bean>
<!--配置增强对象,增强代码写在这里-->
<bean id="transactionManager" class="com.aiitec.utils.TransactionManager">
<property name="connectionUtils" ref="connectionUtils"></property>
</bean>
<bean id="connectionUtils" class="com.aiitec.utils.ConnectionUtils"></bean>
2.3配置切面
<aop:config>
<!--配置切面-->
<aop:aspect id="transactionAdvice" ref="transactionManager">
<!--前置通知-->
<aop:before method="beginTransaction" pointcut="execution(* com.aiitec.service.impl.*.*(..))"></aop:before>
<!--
method:选择要织入的增强方法
aop:before会在代理对象的方法执行之前执行,往下after-returning代表之后执行,after-throwing代表发生异常后执行,after表示最终必会执行
pointcut:使用切入点表达式,指定切入点execution(切入点表达式)
全通配写法:* *..*.*(..)
完整的写法:public void com.aiitec.service.impl.AccountServiceImpl.findAll()
修饰符 返回值 包名 类名 方法名(参数)
访问修饰符:可以省略
返回值:可以用*表示所有类型的返回值,包括void
包名:
可以多少层就写多少个*,com.aiitec.service.impl-->*.*.*.* 表示通配
也可以用*..表示所有包下的任意层子包
类名:可以用*表示通配
方法名:可以用*表示通配
参数:
基本类型直接写,如int
引用类型写包名+类名,如java.lang.String
可以用*表示任意类型的参数,但是不包括无参
用..表示任意类型的参数,包括无参
通常使用的写法:
* com.aiitec.service.impl.*.*(..)
-->
<!--后置通知-->
<aop:after-returning method="commit" pointcut="execution(* com.aiitec.service.impl.*.*(..))"></aop:after-returning>
<!--异常通知-->
<aop:after-throwing method="rollback" pointcut="execution(* com.aiitec.service.impl.*.*(..))"></aop:after-throwing>
<!--最终通知-->
<aop:after method="relese" pointcut-ref="pointCut"></aop:after>
<!--重用切入点表达式
可以将前面的通知标签中的pointcut属性都替换成point-ref="pointCut",避免重复写切入点表达式
注意:<aop:pointcut>写在<aop:aspect>标签内部时,只能被当前的的切面配置引用,
也可以写在<aop:config>标签内<aop:aspect>标签外,这样可以被多个<aop:aspect>标签内引用,
前提是<aop:pointcut>必须定义在引用它的<aop:aspect>之前
-->
<aop:pointcut id="pointCut" expression="execution(* com.aiitec.service.impl.*.*(..))"></aop:pointcut>
</aop:aspect>
</aop:config>
配置环绕通知(实际上是将通知的配置放在了编码中)
<aop:config>
<!--配置切面-->
<aop:aspect id="transactionAdvice" ref="transactionManager">
<!--环绕通知,此时需要在增强类中定义一个配置环绕通知的方法-->
<aop:around method="arundAdvice" pointcut="execution(* com.aiitec.service.impl.*.*(..))"></aop:around>
</aop:aspect>
</aop:config>
public Object arundAdvice(ProceedingJoinPoint pjp){
Object result=null;
try {
Object[] args=pjp.getArgs();//获取方法参数
beginTransaction();//前置通知
result=pjp.proceed(args);//执行目标方法
commit();//后置通知
} catch (Throwable throwable) {
rollback();//异常通知
throwable.printStackTrace();
}finally {
relese();//最终通知
}
return result;
}
ProceedingJoinPoint接口由aspectJ提供