和之前关于Aop的注解方式的实现一样,首先需要配置pom.xml。配置aop的环境。其次计算器Calculator类与实现类CalculatorImpl没有改变。有变化的是切面类即CalculatorLogging。所有的方法不要注解,如下:
package com.yc.spring.aop.impl;
import java.util.Arrays;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.stereotype.Component;
@Component("calculatorlogging")
public class CalculatorLogging {
public void beforeMethod(JoinPoint jp){
String method = jp.getSignature().getName();
Object[] objs = jp.getArgs();
System.out.println("开始执行"+method+ ",计算数据是:" + Arrays.toString(objs));
}
public void afterReturingMethod(JoinPoint jp, Object result){
String method = jp.getSignature().getName();
System.out.println("执行"+method + "获得的结果是" + result);
}
public void afterThrowingMethod(JoinPoint jp,Throwable e){
String method = jp.getSignature().getName();
System.out.println("执行"+method + "发生"+ e.getMessage());
}
public void afterMethod(JoinPoint jp){
String method = jp.getSignature().getName();
System.out.println("执行"+method + "完成...");
}
//这里补充了上篇没有讲到的around
public Object around(ProceedingJoinPoint pjp){
String method = pjp.getSignature().getName();
Object[] objs = pjp.getArgs();
System.out.println("开始执行"+method+ ",计算数据是:" + Arrays.toString(objs));
Object retVal=null;
try {
//调用核心逻辑
retVal = pjp.proceed();
System.out.println("执行"+method + "完成...");
} catch (Throwable e) {
System.out.println("执行"+method + "发生"+ e.getMessage());
}
System.out.println("执行"+method + "获得的结果是" + retVal);
return retVal;
}
}
我们在bean.xml中创建切面对象
<?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:util="http://www.springframework.org/schema/util"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- bean就由spring容器创建好的对象 -->
<!-- 指定可以做为spring容器管理的对象的包 -->
<context:component-scan base-package="com.yc.spring" />
<bean id="calculatorLogging" class="com.yc.spring.aop.impl.CalculatorLogging"></bean>
<aop:config>
<aop:pointcut expression="execution(public * com.yc.spring.aop..*.*(..))" id="myPointcut" /> <!-- 配置切点 -->
<aop:aspect id="myAspect" ref="calculatorLogging">
<aop:before method="beforeMethod" pointcut-ref="myPointcut"/>
<aop:after method="afterMethod" pointcut-ref="myPointcut" />
<aop:after-returning method="afterReturingMethod" pointcut-ref="myPointcut" returning="result"/>
<aop:after-throwing method="afterThrowingMethod" pointcut-ref="myPointcut" throwing="e" />
<!--<aop:around method="around" pointcut-ref="myPointcut" />-->
</aop:aspect>
</aop:config>
</beans>
aop:pointcut 声明切入点
aop:aspect 声明切面
aop:before 声明前置通知
aop:after 声明后置通知
aop:after-returning 声明后置返回通知
aop:after-throwing 声明后置异常通知
aop:around 声明环绕通知
切入点:其定义在config的第一层子目录,可以被其他所有的aspect所引用;当然pointcut还可以定义在aop:aspect的子目录,但是此时只能被该aspect所引用;id定义的是该pointcut的名字;aop:pointcut可以单独定义,也可以使用 aop:around中所示的定义方法
切面:id是指该切面的名字,ref指的是它所引用的切面类
通知:method指的是其所位于的aspect所引用的切面类中的方法名,pointcut-ref指的是引用的切点
后置返回通知需要配置returning,且规则与注解方式一致,需要保持与后置返回通知方法的参数名一致。
后置异常通知,需要配置args-names和throwing,且保持与方法中异常的参数名一致