Spring中的AOP

蹲街弑〆低调 提交于 2020-01-15 05:02:15

概念

连接点(Join Point):业务层接口都是连接点
切入点(Point Cut):不需要被增强的方法

所有的切入点都是连接点,但不时所有的连接点都是切入点

前置通知:被执行方法前
后置通知:被执行方法后
异常通知:异常
最终通知:finally里中的
环绕通知:整个通知过程

spring中基于xml的AOP配置步骤

1、把通知Bean也交给spring来管理
2、使用aop:conf标签表明开始AOP配置
3、使用aop:aspect标签表明配置切面
id属性,是给切面提供一个唯一标识
ref属性,是指定通知类bean的ID
4、在aop:aspect标签的内部使用对应标签来配置通知的类型,before、after等等
5、pointcut属性,用于指定切入点表达式,该表达式的含义是对业务层中的哪些方法进行增强。
6、切入点表达式写法:
关键字:execution(表达式)
表达式:
修饰符 返回值 包全限定名.方法名(参数)

execution(void com.lingmou.service.IUserServiceImpl.login()
	返回值可以省略,返回值可以用通配符*,表示任意返回值
execution(* com.lingmou.service.IUserServiceImpl.login()

包名可以使用通配符,表示任意包,但是有几个包要写几个*

execution(* *.*.*.IUserServiceImpl.login()

包名可以省略

execution(* *..IUserServiceImpl.login()

类名和方法名都可以使用*来实现通配

execution(* *.*.*.*.login()

方法名也可以

execution(* *.*.*.*.*()

参数列表
可以直接写数据类型 int
引用类型也包名、类名的方法 java.lang.String
类型可以使用通配符,表示任意类型,但是必须有参数。

execution(* *..*.*(int)
execution(* *..*.*(*)

使用…表示有无参数都可以

execution(* *..*.*(..)

实际开发中,表达式的通常写法,切到业务层实现类中的所有方法

* com.lingmou.service.impl.*.*(..)		

这个表达式是使用aspectj包来解析的。

<bean id="logger" class="com.lingmou.utils.Logger"></bean>

<aop:conf>
    <aop:aspect id="logAdvice" ref="logger">
        <!--配置通知的类型,并且建立通知方法和切入点方法关联-->
    	<aop:before method="printLog" pointcut="execution(public void com.lingmou.service.IUserServiceImpl.login())"></aop:before>
	</aop:aspect>
</aop:conf>

四种常用的通知类型

  1. 前置通知 aop-before
  2. 后置通知 aop-after-returning:它和异常通知只能执行一个
  3. 异常通知 aop-after-throwing:它和后置通知只能执行一个
  4. 最终通知 aop-after
    配置切入点表达式
此标签写在切面内部,只能当前切面是用,它还可以写在外面,此时就变成所有切面可用。
<aop:pointcut id="" expression=""></aop:pointcut>
  1. 环绕通知 aop-around
    当配置了环绕通知后,切入点方法没有执行,而通知方法执行了。
    分析:通过对比动态代理中的环绕通知代码,发现动态代理中的环绕通知有明确的业务层切入点方法调用。
    Spring框架为我们提供了接口:ProceedingJoinPoint,该接口有一个方法proceed(),此方法就相当于明确调用切入点方法。该接口可以作为环绕通知的方法参数,在程序执行时,spring框架会为我们提供该接口的实现类。
public void around(ProceedingJoinPoint pjp){
	Object ret = null;
 	try{
 	    System.out.println("前置通知");
 		Object[] args = pjp.getArgs();//得到方法所需的参数
 		ret = pjp.proceed(args);	//明确调用业务层方法(切入点方法)
 		System.out.println("后置通知");
 		return ret; 	
  	}catch(Throwable t){
  		System.out.println("异常通知");
		throw new RuntimeException(t);
	}finally{
		System.out.println("最终通知");
	}
	
}

spring中的环绕通知:它是spring为了我们提供的一种可以在代码中手动控制增强方法何时执行的方式。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!