【Spring笔记】08、基于注解形式的AOP实现

二、实现注解实现 通知 ,aop

a.jar
    与 实现接口 的方式相同
b.配置
    将业务类、通知 纳入springIOC容器
    开启注解对AOP的支持<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
    业务类 addStudent -  通知 

c.编写
    
    
通知:
@Aspect  //声明该类 是一个 通知
public class LogBeforeAnnotation  {

}

注意:通过注解形式 将对象增加到 ioc容器时,需要设置扫描器
<context:component-scan base-package="org.lanqiao.aop"></context:component-scan>
    
扫描器会将指定的包中的  @Componet @Service  @Respository   @Controller修饰的类产生的对象增加到IOC容器中
@Aspect不需要 加入扫描器,只需要开启即可:<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

通过注解形式 实现的aop,如果想获取 目标对象的一些参数,则需要使用一个对象:JointPoint

注解形式的返回值:
a.声明返回值的参数名:
    @AfterReturning( pointcut= "execution(public * addStudent(..))" ,returning="returningValue"
    public void myAfter(JoinPoint jp,Object returningValue) //returningValue是返回值,但需要告诉spring
        System.out.println("返回值:"+returningValue );
注解形式实现aop时,通知的方法的参数不能多、少

实现接口形式、注解形式 只捕获声明的特定类型的异常,而其他类型异常不捕获。
cath()

LogAspectAnnotation.java

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.err.println("《【环绕】发生异常时:异常通知");
			//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]注解形式-最终通知-----通知》----");
	}
	
	
}

猜你喜欢

转载自blog.csdn.net/kuaileky/article/details/89502153