定义切面(包含五种通知):
import org.aspectj.lang.ProceedingJoinPoint;
public class MyXmlServiceAop {
public void beforeHandler(String name, int age) {
System.out.println("前置通知:" + name + ":age=" + age);
}
public void aroundHandler(ProceedingJoinPoint jointPoint) {
try {
System.out.println("环绕通知开始");
String name = (String) jointPoint.proceed();
jointPoint.proceed();
System.out.println(name + "环绕通知结束");
} catch (Throwable e) {
}
}
public void afterHandler() {
System.out.println("后置通知");
}
public void returnHandler(Object name) { //在返回通知中获取返回值
System.out.println("返回通知:" + name);
}
public void throwExceptionHandler(Throwable ex) {
System.out.println("异常通知:" + ex.getMessage());
}
}
定义service及切点方法:
public interface MyXmlService {
String handlerXml(String name, int age);
}
public class MyXmlServiceImpl implements MyXmlService {
public String handlerXml(String name, int age) {
//int a = 1 / 0; //异常通知模拟
System.out.println(name + ":xml处理类!");
return name;
}
}
application-context.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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.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">
<bean id="serviceAop" class="com.tanlei.service.MyXmlServiceAop"></bean>
<aop:config>
<aop:aspect ref="serviceAop">
<aop:pointcut expression="execution(* com.tanlei.service.MyXmlService.handlerXml(..)) and args(name,age)" id="handlerXml"/> <!-- 带参 切点-->
<aop:pointcut expression="execution(* com.tanlei.service.MyXmlService.handlerXml(..))" id="handlerXml2"/> <!-- 不带参 切点 -->
<aop:before method="beforeHandler" pointcut-ref="handlerXml" arg-names="name,age" /> <!-- 前置通知,传递参数 -->
<aop:around method="aroundHandler" pointcut-ref="handlerXml2"/> <!-- 环绕通知 -->
<aop:after method="afterHandler" pointcut-ref="handlerXml2"/> <!-- 后置通知 -->
<aop:after-returning method="returnHandler" pointcut-ref="handlerXml2" returning="name"/> <!-- 返回通知 -->
<aop:after-throwing method="throwExceptionHandler" throwing="ex" pointcut-ref="handlerXml2"/> <!-- 异常通知 -->
</aop:aspect>
</aop:config>
<bean id="myXmlService" class="com.tanlei.service.MyXmlServiceImpl"></bean>
</beans>
main测试类:
public class Main {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml");
MyXmlService service = (MyXmlService) context.getBean("myXmlService");
String name = service.handlerXml("t6", 25);
System.out.println(name);
}
}
值得注意的是,当使用环绕通知后,返回通知和方法返回值中是获取不到切点方法的返回值的,因为在环绕通知中已调用切点方法。