除了使用xml配置外,还可以使用注解的方式实现上述几种通知。
LogAspectAnnotation.java:
package aop.Aspe;
import org.aspectj.lang.ProceedingJoinPoint;
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;
@Component("logAnn")
@Aspect
public class LogAspectAnnotation {
@Before("execution(public * springProject.Student.add(..))")
public void bBefore() {
System.out.println("@@@前置通知");
}
@AfterReturning("execution(public * springProject.Student.add(..))")
public void bAfter() {
System.out.println("@@@后置通知");
}
@AfterThrowing("execution(public * springProject.Student.add(..))")
public void bThrowing() {
System.out.println("@@@异常通知");
}
//环绕通知 ,参数ProceedingJoinPoint
@Around("execution(public * springProject.Student.add(..))")
public void myAround(ProceedingJoinPoint jp ) {
//方法之前:前置通知
System.out.println("《【环绕】方法之前:前置通知");
try {
//方法执行时
jp.proceed() ;//执行方法
//方法之前之后:后置通知
System.out.println("《【环绕】方法之前之后:后置通知");
}catch(Throwable e) {
//发生异常时:异常通知
System.out.println("《【环绕】发生异常时:异常通知");
}finally {
//最终通知
System.out.println("《【环绕】最终通知");
}
}
}
tips:
@Component("logAnn"): 把这个类加入ioc容器,id为logAnn。 必须在xml中,加入xmlns:context="http://www.springframework.org/schema/context" 然后调用扫描器:<context:component-scan base-package="aop.Aspe"></context:component-scan> 扫描器 会将 指定的包 中的 @Componet @Service @Respository @Controller修饰的类产生的对象 增加到IOC容器中
@Aspect: 声明这个类是个通知。 不需要通过扫描器,只需要在xml文件中开启即可:<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
@Before("execution(public * springProject.Student.add(..))"): 声明这个方法是个前置通知,关联的业务方法为add。
@AfterReturning("execution(public * springProject.Student.add(..))") 声明这个方法是个前置通知,关联的业务方法为add。
@AfterThrowing("execution(public * springProject.Student.add(..))") 声明这个方法是个异常通知。
@Around("execution(public * springProject.Student.add(..))") 声明这个方法为环绕通知。
上述各个通知对应的方法名可以随便取。
如果想要获取目标对象的一些参数,则需要使用一个对象:JointPoint。
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 {
//前置通知
@Before("execution(public * addStudent(..))") //属性:定义切点
public void myBefore(JoinPoint jp) {
System.out.println("《注解形式-前置通知》:目标对象:"+jp.getTarget()+",方法名:"+jp.getSignature().getName() +",参数列表:"+ jp.getArgs().length );
}
//后置通知
@AfterReturning( pointcut= "execution(public * addStudent(..))" ,returning="returningValue" )
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]注解形式-最终通知-----通知》----");
}
}
注解形式的返回值: a.声明返回值 的参数名:
@AfterReturning( pointcut= "execution(public * addStudent(..))" ,returning="returningValue" )
public void myAfter(JoinPoint jp,Object returningValue) {//returningValue是返回值,但需要告诉spring
System.out.println("返回值:"+returningValue );
b: 注解形式实现aop时,通知的方法的参数不能多、少。
c: 实现接口形式、注解形式 只捕获声明的特定类型的异常,而其他类型异常不捕获。
d: 异常通知,可以只在某个特定异常才输出。
@AfterThrowing(pointcut= "execution(public * addStudent(..))",throwing="e")
public void myException(JoinPoint pj, NullPointerException e) {//此异常通知 只会捕获NullPointerException类型的异常
System.out.println("&&&&&&《注解形式-异常通知》----e:"+e.getMessage());
}
|