spring-aop

AOP:面向方面编程

一个普通的类 -> 有特定功能的类
a.继承类 b.实现接口 c.注解 d.配置
在这里插入图片描述

jar:

spring 的基础jar
另需要
spring-aop.jar
aopaliance.jar
aspectjweaver.jar

方式一:实现接口
前置通知: 实现  org.springframework.aop.MethodBeforeAdvice  接口
后置通知:实现 org.springframework.aop.AfterReturningAdvice 接口
异常通知:实现 org.springframework.aop.ThrowsAdvice 接口
参数 :
①都有的参数
	Method method, Object[] args, Object target
	method :反射包中 ,代表具体的执行方法
	args:方法参数列表
	target:目标对象
②不同的参数
	在后置通知中: 第一个参数 为 Object returnValue 方法的 返回值
	在异常通知中:最后一个参数为 需要进行捕获的  《异常类型》
			可以实现的方法通过源码可以发现:
				public void afterThrowing(Method, args, target, ThrowableSubclass)
				public void afterThrowing( ThrowableSubclass)
			两个方法任选其一
环绕通知 : 实现 org.aopalliance.intercept.MethodInterceptor 接口
参数:org.aopalliance.intercept.MethodInvocation  invocation
环绕通知可实现前面三者  在invocation.proceed()  
	之前  可以作为前置通知
	之后 可以作为后置通知 
	在catch中 为异常通知
	在finally 中  为最终通知

在这里插入图片描述
在这里插入图片描述

案列: 环绕通知
实现接口
package org.aop;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class LogAround  implements MethodInterceptor{
	@Override
	public Object invoke(MethodInvocation invocation) throws Throwable {
		Object result  = null ;
		//方法体1...
		try {
			//方法体2...
			System.out.println("用环绕通知实现的[前置通知]...");
			// invocation.proceed() 之前的代码:前置通知
			 result  = invocation.proceed() ;//控制着目标方法的执行  ,addStudent()
			//result 就是目标方法addStudent()方法的返回值
//			 invocation.proceed() 之后的代码:后置通知
			System.out.println("用环绕通知实现的[后置通知]...:");
			System.out.println("目标对象target"+invocation.getThis()+
			",调用的方法名:"+invocation.getMethod().getName()+
			",方法的参数个数:"+invocation.getArguments().length+",返回值:"+result);	
		}catch(Exception e) {
			//方法体3...
			//异常通知
			System.out.println("用环绕通知实现的[异常通知]...");
		}
		return result;//目标方法的返回值
	}

}
在applicationContext.xml中配置
<!-- 将准备转为 通知的类 纳入ioc容器 -->
	<bean id="logAround  " class="org.aop.LogAround  "></bean>
	<aop:config>
		<!-- 切入点(连接线的一端:业务类的具体方法) -->
		<aop:pointcut    id="around"
		expression="execution(public * org.service.impl.StudentServiceImpl.addStudent(..))" />
		<!-- (连接线的另一端:通知 类)-->
		<aop:advisor advice-ref="logAround  "  pointcut-ref="around" /> 
		 </aop:aspect>	
	</aop:config>
方式二:基于注解
配置 <aop:aspectj-autoproxy></aop:aspectj-autoproxy> 开启对注解的支持
相关注解
①@Aspect 作用于类

@Aspect 声明该类是一个通知
public class LogforAnnotation(){}

@Aspect 不需要加入扫描器 只需要开启即可 aop:aspectj-autoproxy

②通知的方法注解
前置通知:	@Before("execution()")  // 切入点
后置通知:	@AfterReturning( pointcut= "execution( )" ,returning="returningValue" ) 
环绕通知:	@Around("execution( )")
异常通知:	@AfterThrowing(pointcut= "execution ( )",throwing="e")
最终通知:	@After("execution( )"

注解形式的返回值:
声明 返回值 的参数名

 @AfterReturning(pointcut="excution(public *addStudent(..))",returning = "returnValue"
	public void myAfter(JoinPoing jp, Object returnValue){
		System.out.println("《注解形式-后置通知》:目标对象:"+jp.getTarget()+
		",方法名:"+jp.getSignature().getName() +",参数列表:"+ 
		 jp.getArgs().length+",返回值:"+returningValue );
	}
环绕通知的参数类型为:ProceedingJoinPoint 
注解形式实现 通知的参数不能多 也不能少
实现接口 、注解形式 只能捕获声明的特定类型的异常 而其他异常 不捕获
方式三:基于Scheme配置
>>>>不实现接口 不使用注解 : 通过配置 将类 变成通知

Schema方式实现:
a、编写一个普通的类 public class LogAfter{}
b、将该类 通过配置 转为一个通知

案例

通知方法

package org.aop;

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);
	}
}

xml配置

<!-- 将准备转为 通知的类 纳入ioc容器 -->
	<bean id="logSchema" class="org.aop.LogSchema"></bean>
	<aop:config>
		<!-- 切入点(连接线的一端:业务类的具体方法) -->
		<aop:pointcut expression="execution(public * org.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>

可以配置多个通知

总结

如果 要获取目标对象 信息
注解、Schema: JoinPoint
接口 :Method method,Object[] args, Object target
schema 形式 和 注解形式相似 不同之处 注解形式 使用了 注册 @After
schema形式进行 了多余的配置

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值