在Spring中,我们可以通过AOP标签来定义切面、切入点和通知。
所有aop标签如下:
<aop:config> aop定义开始(有序)
<aop:pointcut/> 切入点定义
<aop:advisor/> 通知定义
<aop:aspect> 切面定义开始(内部无序)
<aop:pointcut/> 切入点定义
<aop:before/> 前置通知定义
<aop:after-returning/> 后置返回通知定义
<aop:after-throwing/> 后置异常通知定义
<aop:after/> 后置最终通知定义
<aop:around/> 环绕通知定义
<aop:declare-parents/> 引入定义
</aop:aspect>
</aop:config>
1.前置通知实例
调用类
package cn.belle.test;
public class HelloWorldService {
public void sayBefore(String param) {
System.out.println("我是前置通知");
}
}
切面类
package cn.belle.test;
public class HelloAspect {
public void beforeAdvice(String param) {
System.out.println("我是前置通知的通知方法"+param);
}
}
Spring配置文件
<?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"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<bean id="helloWorldService" class="cn.belle.test.HelloWorldService"/>
<bean id="aspect" class="cn.belle.test.HelloAspect" />
<aop:config>
<aop:aspect ref="aspect">
<aop:before method="beforeAdvice(java.lang.String)" arg-names="param" pointcut="execution(* cn.belle..*.sayBefore(..)) and args(param)" />
</aop:aspect>
</aop:config>
</beans>
pointcut :切入点;method :切面内通知方法 ; arg-names:切面类通知方法的参数名字(这里参数是与调用类同名的参数)
测试类
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
HelloWorldService helloworldService = ctx.getBean("helloWorldService", HelloWorldService.class);
helloworldService.sayBefore("before");
}
2.后置最终通知
调用类
package cn.belle.test;
public class HelloWorldService {
public void sayAfterFinally() {
System.out.println("我是后置最终通知");
}
}
切面类
package cn.belle.test;
public class HelloAspect {
public void afterFinallyAdvice() {
System.out.println("我是后置最终通知的通知方法");
}
}
配置文件
<bean id="helloWorldService" class="cn.belle.test.HelloWorldService"/>
<bean id="aspect" class="cn.belle.test.HelloAspect" />
<aop:config>
<aop:aspect ref="aspect">
<aop:after pointcut="execution(* cn.belle..*.sayAfterFinally(..))" method="afterFinallyAdvice"/>
</aop:aspect>
</aop:config>
测试类
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
HelloWorldService helloworldService = ctx.getBean("helloWorldService", HelloWorldService.class);
helloworldService.sayAfterFinally();
}
3.后置返回通知
调用类
package cn.belle.test;
public class HelloWorldService {
public boolean sayAfterReturning() {
System.out.println("我是后置返回通知");
return true;
}
}
切面类
package cn.belle.test;
public class HelloAspect {
public void afterReturningAdvice(Object retVal) {
System.out.println("我是后置返回通知的通知方法"+retVal);
}
}
配置文件
<bean id="helloWorldService" class="cn.belle.test.HelloWorldService"/>
<bean id="aspect" class="cn.belle.test.HelloAspect" />
<aop:config>
<aop:aspect ref="aspect">
<aop:after-returning pointcut="execution(* cn.belle..*.sayAfterReturning(..))" method="afterReturningAdvice" arg-names="retVal" returning="retVal" />
</aop:aspect>
</aop:config>
returning 指的是调用类返回值
测试类
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
HelloWorldService helloworldService = ctx.getBean("helloWorldService", HelloWorldService.class);
helloworldService.sayAfterReturning();
}
4.后置异常通知
调用类
package cn.belle.test;
public class HelloWorldService {
public void sayAfterThrowing() {
System.out.println("我是后置异常通知");
throw new RuntimeException();
}
}
切面类
package cn.belle.test;
public class HelloAspect {
public void afterThrowingAdvice(Exception exception) {
System.out.println("我是后置异常通知的通知方法"+exception);
}
}
配置文件
<bean id="helloWorldService" class="cn.belle.test.HelloWorldService"/>
<bean id="aspect" class="cn.belle.test.HelloAspect" />
<aop:config>
<aop:aspect ref="aspect">
<aop:after-throwing pointcut="execution(* cn.belle..*.sayAfterThrowing(..))" method="afterThrowingAdvice" arg-names="exception" throwing="exception" />
</aop:aspect>
</aop:config>
测试类
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
HelloWorldService helloworldService = ctx.getBean("helloWorldService", HelloWorldService.class);
helloworldService.sayAfterThrowing();
5.环绕通知
调用类
package cn.belle.test;
public class HelloWorldService {
public void sayAround(String param) {
System.out.println("我是环绕通知"+ param);
}
}
切面类
package cn.belle.test;
import org.aspectj.lang.ProceedingJoinPoint;
public class HelloAspect {
public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable {
Object retVal = pjp.proceed(new Object[] { "replace" });
System.out.println("环绕通知的通知方法");
return retVal;
}
}
配置文件
<bean id="helloWorldService" class="cn.belle.test.HelloWorldService"/>
<bean id="aspect" class="cn.belle.test.HelloAspect" />
<aop:config>
<aop:aspect ref="aspect">
<aop:around pointcut="execution(* cn.belle..*.sayAround(..))" method="aroundAdvice" />
</aop:aspect>
</aop:config>
测试类
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
HelloWorldService helloworldService = ctx.getBean("helloWorldService", HelloWorldService.class);
helloworldService.sayAround("Around");