Aop基于Xml配置(详细):Spring AOP基于XML配置实现4种通知
基于注解:
1、创建通知类 LogAspectAnnotation(),并添加注解@Component("logAnnotation")、@Aspect
@Component("logAnnotation") //将LogAspectAnnotation纳入springIOC容器中
@Aspect //此类是一个通知
public class LogAspectAnnotation {
}
2、编写各种通知方法,并添加各种注解@Before(" ") 、@AfterReturning( pointcut= " " ,returning=" " ) 、@Around(" ")、@AfterThrowing(pointcut= " ",throwing=" ")、 @After(" ")
package org.lanqiao.aop;
import java.util.Arrays;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
//<bean id="logAnnotation" class="org.lanqiao.aop.LogAspectAnnotation">
@Component("logAnnotation") //将LogAspectAnnotation纳入springIOC容器中
@Aspect //此类是一个通知
public class LogAspectAnnotation {
//前置通知(所有名字为addStudent的方法)
@Before("execution(public * addStudent(..))") //属性:定义切点
public void myBefore(JoinPoint jp) {
System.out.println("《注解形式-前置通知》:目标对象:"+jp.getTarget()+",方法名:"+jp.getSignature().getName() +",参数列表个数:"+ jp.getArgs().length ); //参数列表:Array.toString(jp.getArgs())->由于参数是引用类型,会将引用类型的属性值全部打印出来
}
//后置通知
@AfterReturning( pointcut= "execution(public * addStudent(..))" ,returning="returningValue" ) //当要告诉spring多个参数时,需用键值对的形式
public void myAfter(JoinPoint jp,Object returningValue) {//returningValue是返回值,但需要告诉spring
System.out.println("《注解形式-后置通知》:目标对象:"+jp.getTarget()+",方法名:"+jp.getSignature().getName() +",参数列表:"+ jp.getArgs().length+",返回值:"+returningValue );
}
/*环绕通知 ,参数ProceedingJoinPoint
@Around("execution(public * addStudent(..))")
public void myAround(ProceedingJoinPoint jp ) {
//方法之前:前置通知
System.out.println("《【环绕】方法之前:前置通知");
try {
//方法执行时
jp.proceed() ;//执行方法
//方法之前之后:后置通知
System.out.println("《【环绕】方法之前之后:后置通知");
}catch(Throwable e) {
//发生异常时:异常通知
System.out.println("《【环绕】发生异常时:异常通知");
}finally {
//最终通知
System.out.println("《【环绕】最终通知");
}
}*/
//异常通知:如果只捕获特定类型的已存银行,则可以通过第二个参数实现:e
@AfterThrowing(pointcut= "execution(public * addStudent(..))",throwing="e")
public void myException(JoinPoint pj, NullPointerException e) {//此异常通知 只会捕获NullPointerException类型的异常
System.out.println("&&&&&&《注解形式-异常通知》----e:"+e.getMessage());
}
//最终通知
@After("execution(public * addStudent(..))")
public void myAfter() {
System.out.println("《[myAfter]注解形式-最终通知-----通知》----"+this.toString());
}
}
3、xml配置:
<!-- 测试注解完成通知 -->
<!-- 开启注解对AOP的支持 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<!-- 配置扫描器 -->
<context:component-scan base-package="org.lanqiao.aop"></context:component-scan>
基于Schema的XML配置:
package org.lanqiao.aop;
import java.lang.reflect.Method;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
public class LogSchema {
//后置通知方法 :JoinPoint适用于注解
public void afterReturning(JoinPoint jp,Object returnValue) throws Throwable {
System.out.println("》》》》》》》》》》》后置通知:目标对象:"+jp.getThis()+",调用的方法名:"+jp.getSignature().getName()+",方法的参数个数:"+jp.getArgs().length+",方法的返回值:"+returnValue);
}
public void before() {
System.out.println("》》》》》》》》》》》前置通知...");
}
public void whenException(JoinPoint jp,NullPointerException e) {
System.out.println(">>>>>>>>>>>>>>>>异常:" +e.getMessage());
}
//注意:环绕通知 会返回目标方法的返回值,因此返回值为Object
public Object around(ProceedingJoinPoint jp) {
System.out.println("''''''''''''''''''环绕通知:前置通知");
Object result = null ;
try {
result = jp.proceed() ;//执行方法
System.out.println("'''''''''"+jp.getSignature().getName()+","+result);
System.out.println("''''''''''''''''''环绕通知:后置通知");
}catch(Throwable e) {
System.out.println("''''''''''''''''''环绕通知:异常通知");
}
return result ;
}
}
<bean id="logSchema" class="org.lanqiao.aop.LogSchema"></bean>
<aop:config>
<!-- 切入点(连接线的一端:业务类的具体方法) -->
<aop:pointcut expression="execution(public * org.lanqiao.service.impl.StudentServiceImpl.addStudent(..))" id="pcShema"/>
<!-- schema方式 -->
<aop:aspect ref="logSchema">
<!-- 连接线:连接 业务 addStudent 和 通知before -->
<aop:before method="before" pointcut-ref="pcShema"/>
<!-- 连接线:连接 业务 addStudent 和 通知afterReturning -->
<aop:after-returning method="afterReturning" returning="returnValue" pointcut-ref="pcShema"/>
<aop:after-throwing method="whenException" pointcut-ref="pcShema" throwing="e"/>
<!-- 环绕 -->
<aop:around method="around" pointcut-ref="pcShema" />
</aop:aspect>
</aop:config>