在 Spring 的 aop 代理方式中, AspectJ 才是主流。
spring-aop-4.2.4.RELEASE.jar
com.springsource.org.aopalliance-1.0.0.jar
spring-aspects-4.2.4.RELEASE.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
<?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"> <!-- bean definitions here -->
</beans>
@Before
前置通知,相当于 BeforeAdvice
@AfterReturning
后置通知,相当于 AfterReturning
@Around
环绕通知,相当于 MethodInterceptor
@After Throwing
异常抛出通知,相当于 ThrowAdvice
After
最终通知,不管是否异常,改通知都会执行DeclareParents
引介通知,相当于 IntroductionInterceptor
(不要求掌握)可以在方法中传入 JoinPoint 对象,用来获得切点信息
// 要增强的代码
@Before(value = "execution(* com.test.aspectJ.demo1.ProductDao.save(..))")
public void before(JoinPoint joinPoint) {
System.out.println("前置通知=========" + joinPoint);
}
通过 returning 属性,可以定义方法返回值,作为参数:
// result 拿到返回值
@AfterReturning(value = "execution(* com.test.aspectJ.demo1.ProductDao.update(..))", returning = "result")
public void afterReturning(Object result) {
System.out.println("后置通知=========="+result);
}
@Around(value = "execution(* com.test.aspectJ.demo1.ProductDao.delete(..))")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("环绕前通知============");
Object obj = joinPoint.proceed(); //执行目标方法
System.out.println("环绕后通知==========");
return obj;
}
重点:如果不调用 ProceedingJoinPoint 的 proceed 方法,那么目标方法就被拦截了。
通过设置 throwing 属性,可以设置发生异常对象参数
@AfterThrowing(value = "execution(* com.test.aspectJ.demo1.ProductDao.find(..))", throwing = "e")
public void afterThrowing(Throwable e) {
System.out.println("异常抛出通知==========="+e.getMessage());
}
无论是否出现异常,最终通知总是会被执行
@AfterThrowing(value = "execution(* com.test.aspectJ.demo1.ProductDao.findAll(..))", throwing = "e")
public void afterThrowing(Throwable e) {
System.out.println("异常抛出通知==========="+e.getMessage());
}
通过 execution
函数,可以定义切点的方式切入
语法:
execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)
例如:
定义切面类:
@Aspect
public class MyAspectAnno {}
@Point
进行定义private void
无参数方法,方法名为切点名@Pointcut(value = "execution(* com.test.aspectJ.demo1.ProductDao.save(..))")
private void myPointcut1() {}
public class MyAspectXml {
//前置通知
public void before(JoinPoint joinPoint) {
System.out.println("XML方法的前置通知=========="+joinPoint);
}
// 后置通知
public void afterReturning(Object result) {
System.out.println("XML方法的后置通知==========="+result);
}
//环绕通知
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("XML方式的环绕前通知==========");
Object obj = joinPoint.proceed();
System.out.println("XML方式的环绕后通知");
return obj;
}
// 异常抛出通知
public void afterThrowing(Throwable e) {
System.out.println("XML方法的异常抛出通知"+e.getMessage());
}
// 最终通知
public void after() {
System.out.println("XML方法的最终通知");
}
}
<!-- 配置切面类 -->
<bean id="myAspectXml" class="com.test.aspectJ.demo2.MyAspectXml" />
<!-- aop 的相关配置 -->
<aop:config>
<!-- 配置切入点 -->
<aop:pointcut id="pointcut1" expression="execution(* com.test.aspectJ.demo2.CustomerDaoImpl.save())" />
<aop:pointcut id="pointcut2" expression="execution(* com.test.aspectJ.demo2.CustomerDaoImpl.update())" />
<aop:pointcut id="pointcut3" expression="execution(* com.test.aspectJ.demo2.CustomerDaoImpl.delete())" />
<aop:pointcut id="pointcut4" expression="execution(* com.test.aspectJ.demo2.CustomerDaoImpl.findOne())" />
<aop:pointcut id="pointcut5" expression="execution(* com.test.aspectJ.demo2.CustomerDaoImpl.findAll())" />
<!-- 配置AOP的切面 -->
<aop:aspect ref="myAspectXml">
<!-- 配置前置通知 -->
<aop:before method="before" pointcut-ref="pointcut1" />
<!-- 配置后置通知 -->
<aop:after-returning method="afterReturning" pointcut-ref="pointcut2" returning="result" />
<!-- 配置环绕通知 -->
<aop:around method="around" pointcut-ref="pointcut3" />
<!-- 配置异常抛出通知 -->
<aop:after-throwing method="afterThrowing" pointcut-ref="pointcut4" throwing="e"/>
<!-- 配置最终通知 -->
<aop:after method="after" pointcut-ref="pointcut5" />
</aop:aspect>
</aop:config>
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有