一.常用概念:
- 原有功能: 切点 pointcut
- 前置通知: 在切点之前执行的功能, before advice
- 后置通知: 在切点之后执行的功能, after advice
- 异常通知: 如果切点执行过程中出现异常,则触发异常通知 throws advice
- 切面: 所有功能的总称
- 织入:把切面嵌入到原有功能的过程叫织入
二.spring提供了两种AOP实现方式
2.1 Schema-based
2.1.1: 每个通知必须实现接口或类
2.1.2:配置spring文件时在<aop:config>中配置
2.2 AspectJ
2.2.1: 每个通知不需要实现接口或类
2.2.2: 配置spring文件时在<aop:config>中的子标签<aop:aspect>配置
三. Schema-based 实现步骤
-
导入jar包
-
新建通知类
2.1 前置通知类2.1.1 Method method: 切点方法对象(反射)
2.1.2 Object[] args: 切点方法参数数组
2.1.3 Object target: 切点类对象
public class MyBeforeAdvice implements MethodBeforeAdvice{
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("执行前置通知");
}
}
2.2后置通知类
2.2.1 Object returnValue : 切点方法返回值
2.2.2 Method method: 切点方法对象(反射)
2.2.3 Object[] args: 切点方法参数数组
2.2.4 Object target: 切点类对象
public class MyAfterAdvice implements AfterReturningAdvice{
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("执行后置通知");
}
}
3.配置spring配置文件
<!-- 前置通知类 -->
<bean id="MyBeforeAdvice" class="com.mlj.springstudy.MyBeforeAdvice"></bean>
<!-- 后置通知类 -->
<bean id="MyAfterAdvice" class="com.mlj.springstudy.MyAfterAdvice"></bean>
<!-- 切点类 -->
<bean id="Demo" class="com.mlj.springstudy.Demo"></bean>
<!-- aop配置 -->
<aop:config>
<!-- 配置切点 -->
<aop:pointcut expression="execution(* com.mlj.springstudy.Demo.demo2())" id="mypoint"/>
<!-- 配置通知 -->
<aop:advisor advice-ref="MyBeforeAdvice" pointcut-ref="mypoint"/>
<aop:advisor advice-ref="MyAfterAdvice" pointcut-ref="mypoint"/>
</aop:config>
三,配置异常通知步骤(AspectJ方式)
1.只有当切入点出现异常时才会触发异常通知
2.在spring中只有AspectJ提供了异常通知的方法
3.实现步骤
3.1 新建异常通知类(不需要实现接口)
public class MyThrowsAdvice {
public void myExcution(Exception e) {
System.out.println("执行异常通知"+e.getMessage());
}
}
3.2 在spring配置文件中配置
<!-- 切入点类 -->
<bean id="Demo" class="com.mlj.springstudy.Demo"></bean>
<!-- 异常通知类 -->
<bean id="MyThrowsAdvice" class="com.mlj.springstudy.MyThrowsAdvice"></bean>
<!-- 配置aop -->
<aop:config>
<aop:aspect ref="MyThrowsAdvice">
<!-- 切入点 -->
<aop:pointcut expression="execution(* com.mlj.springstudy.Demo.*(..))" id="mypoint"/>
<!-- 异常通知 -->
<aop:after-throwing method="myExcution" pointcut-ref="mypoint" throwing="e"/>
</aop:aspect>
</aop:config>
四,环绕通知(schema-based)
1.新建环绕通知类
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class MyArroud implements MethodInterceptor{
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("环绕前置");
Object proceed = invocation.proceed();//放行,调用切点方式
System.out.println("环绕后置");
return proceed;
}
}
2.在spring配置文件中配置
<!-- 切点类 -->
<bean id="Demo" class="com.mlj.springstudy.Demo"></bean>
<!-- 环绕通知类 -->
<bean id="MyArroud" class="com.mlj.springstudy.MyArroud"></bean>
<!-- 基于schema-base配置 -->
<aop:config>
<aop:pointcut expression="execution(* com.mlj.springstudy.Demo.*(..))" id="mypointcut"/>
<aop:advisor advice-ref="MyArroud" pointcut-ref="mypointcut"/>
</aop:config>