spring 的 aop 笔记
发布于: 11 小时前
spring 的 aop
需要引入 pom 的依赖
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<optional>true</optional>
</dependency>
复制代码
spring 的切面编程有两种:spring AOP 和 AspectJ
在 spring2 以后就支持 AspectJ。
aspect 切面执行顺序:
前置通知 before
环绕通知 around
后置通知 after-retruning
异常通知 after-throwing
最终通知 after
前置通知:模拟执行权限检查....目标类是:com.xyj.bean.UserDaoImpl@72057ecf 被植入增强处理的目标方法为:login 环绕开始:执行目标方法之前,模拟开启事务....执行-----userDaoImpl->login....最终通知:模拟方法结束后释放资源...环绕结束:执行目标方法之后,模拟关闭事务....后置通知:模拟记录日志...被植入增强处理的目标方法为:login
两种使用方式:
xml 配置
创建的applicationconfig.xml 需要引入:xmlns:aop="http://www.springframework.org/schema/aop";
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
<?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">
<!--1 目标类-->
<bean name="userDao" class="com.xyj.bean.UserDaoImpl"></bean>
<!--2 切面类-->
<bean name="myAspect" class = "com.xyj.bean.AspectDemo"></bean>
<!--3 切面配置-->
<aop:config>
<aop:aspect id="aspect" ref="myAspect">
<!-- [1]配置切入点-->
<aop:pointcut id="myPointcut" expression="execution(* com.xyj.bean.*.*(..))"/>
<!-- [2]配置通知-->
<!--* 前置通知-->
<aop:before method="myBefore" pointcut-ref="myPointcut"></aop:before>
<!--* (成功则执行,异常则不执行)后置通知-->
<aop:after-returning method="myAfterReturning" pointcut-ref="myPointcut" returning="joinPoint"></aop:after-returning>
<!--* 环绕通知-->
<aop:around method="myAround" pointcut-ref="myPointcut"></aop:around>
<!--* 异常通知(抛出异常则执行,否则不执行)-->
<aop:after-throwing method="myAfterThrowing" pointcut-ref="myPointcut" throwing="e"></aop:after-throwing>
<!--* 最终通知-->
<aop:after method="myAfter" pointcut-ref="myPointcut"/>
</aop:aspect>
</aop:config>
</beans>
复制代码
package com.xyj.bean;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
/**
* 切面类,在此类中编写通知
*/
public class AspectDemo {
//前置通知 before
public void myBefore(JoinPoint joinPoint){
System.out.println("前置通知:模拟执行权限检查....");
System.out.println("目标类是:"+joinPoint.getTarget());
System.out.println("被植入增强处理的目标方法为:"+joinPoint.getSignature().getName());
}
//后置通知 afterReturning
public void myAfterReturning(JoinPoint joinPoint){
System.out.println("后置通知:模拟记录日志...");
System.out.println("被植入增强处理的目标方法为:"+joinPoint.getSignature().getName());
}
/**
* 环绕通知 around
* ProceedingJoinPoint 是 JoinPoint子接口,表示可执行目标方法
* 1/必须是Object类型的返回值
* 2、必须接收一个ProceedingJoinPoint参数
* 3、必须是throws Throwable
*/
public Object myAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
//1、开始
System.out.println("环绕开始:执行目标方法之前,模拟开启事务....");
//2、执行当前目标方法
Object obj = proceedingJoinPoint.proceed();
//3、结束
System.out.println("环绕结束:执行目标方法之后,模拟关闭事务....");
return obj;
}
//异常通知 afterThrowing
public void myAfterThrowing(JoinPoint joinPoint,Throwable e){
System.out.println("异常通知----:出错了,错误是["+e.getMessage()+"]");
}
//最终通知 after()
public void myAfter(){
System.out.println("最终通知:模拟方法结束后释放资源...");
}
}
复制代码
注解方式
代码:
package com.xyj.bean;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
/**
* 切面类,在此类中编写通知
*/
@Aspect
@Component("aspectDemo2")
public class AspectDemo2 {
//定义切入点表达式
@Pointcut("execution(* com.xyj.bean.*.*(..))")
//切入点方法
public void myPointCut(){
System.out.println("----myPointCut----");
}
//前置通知 before
@Before("myPointCut()")
public void myBefore(JoinPoint joinPoint){
System.out.println("前置通知:模拟执行权限检查....");
System.out.print("目标类是:"+joinPoint.getTarget());
System.out.println("被植入增强处理的目标方法为:"+joinPoint.getSignature().getName());
}
//后置通知 afterReturning
@AfterReturning("myPointCut()")
public void myAfterReturning(JoinPoint joinPoint){
System.out.print("后置通知:模拟记录日志...");
System.out.println("被植入增强处理的目标方法为:"+joinPoint.getSignature().getName());
}
/**
* 环绕通知 around
* ProceedingJoinPoint 是 JoinPoint子接口,表示可执行目标方法
* 1/必须是Object类型的返回值
* 2、必须接收一个ProceedingJoinPoint参数
* 3、必须是throws Throwable
*/
@Around("myPointCut()")
public Object myAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
//1、开始
System.out.println("环绕开始:执行目标方法之前,模拟开启事务....");
//2、执行当前目标方法
Object obj = proceedingJoinPoint.proceed();
//3、结束
System.out.println("环绕结束:执行目标方法之后,模拟关闭事务....");
return obj;
}
//异常通知 afterThrowing
@AfterThrowing(value = "myPointCut()",throwing = "e")
public void myAfterThrowing(JoinPoint joinPoint,Throwable e){
System.out.println("异常通知----:出错了,错误是["+e.getMessage()+"]");
}
//最终通知 after()
@After("myPointCut()")
public void myAfter(){
System.out.println("最终通知:模拟方法结束后释放资源...");
}
}
复制代码
<?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:context="http://www.springframework.org/schema/context"
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/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--指定扫描的包,是注解生效-->
<context:component-scan base-package="com.xyj"/>
<!--启动基于注解的声明式 AspectJ支持-->
<aop:aspectj-autoproxy/>
</beans>
复制代码
划线
评论
复制
发布于: 11 小时前阅读数: 3
版权声明: 本文为 InfoQ 作者【加哥】的原创文章。
原文链接:【http://xie.infoq.cn/article/983381ac5c8e4015d95ec1b03】。文章转载请联系作者。
加哥
关注
还未添加个人签名 2019.02.11 加入
还未添加个人简介
评论