Spring的AOP
AOP:全称是 Aspect Oriented Programming 即:面向切面编程。
AOP也是一种解耦的技术,它就是把我们程序重复的代码抽取出来,在需要执行的时候,使用动态代理的技术,在不修改源码的基础上,对我们的已有方法进行增强。
使用AOP,可以减少重复代码,提高开发效率,让维护更方便
基于Xml的spring AOP
首先是需要导入jar包
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.7</version>
</dependency>
然后在配置文件中,我们需要添加约束
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
接下来就可以进行配置了
<!-- 1.配置通知类 -->
<bean id="#" class="#"></bean>
<!--2.开始AOP的配置-->
<aop:config>
<!--3.开始配置切面(id为切面唯一标识,ref为通知类的id) -->
<aop:aspect id="logAdvice" ref="#">
<!-- 4.配置通知的类型,并且建立通知方法和切入点方法的关联(method为通知类要使用的增强方法)-->
<aop:before method="#" pointcut="execution(* com.service.impl.*.*(..))"></aop:before>
</aop:aspect>
</aop:config>
标准切点表达式的写法:
关键字:execution(表达式)
表达式:访问修饰符 返回值 包名.包名.包名…类名.方法名(参数类型列表)
其中,表达式的访问修饰符是可以省略的,返回值,包名,类名,方法名都可以使用*号进行通配。
<aop:pointcut id="id" expression="execution(* com.service.impl.*.*(..))"></aop:pointcut>
<aop:before method="#" pointcut-ref="id"></aop:around>
这样也可以配置表达式。(实际上aop:pointcut标签应该是配置在aop:aspect外,aop:config内的标签 )
参数列表的写法:
基本数据类型直接写名称:如(int)
应用类型需要全限定类名:如(int,java.lang.String)
也可以使用*号通配某个参数:
如(int,java.lang.String,*)
还有一种全通配写法:如( . . )不管参数列表怎么样,都可以匹配
通知类型:
aop:before :前置通知,在切入点方法执行之前执行
aop:after-returning : 后置通知,在切入点方法正常执行之后值
aop:after-throwing :异常通知,在切入点方法执行产生异常之后执行
aop:after : 最终通知,无论切入点方法是否正常执行它都会在其后面执行
aop:around : Spring提供的一种,通过代码手动控制上面4中通知。
下面看一看代码:
//ProceedingJoinPoint是Spring提供的接口,该接口有一个方法proceed(),此方法用来明确调用切入点方法
public Object aroundPringLog(ProceedingJoinPoint pjp){
Object rtValue = null;
try{
Object[] args = pjp.getArgs();//得到方法执行所需的参数
System.out.println("前置代码位置");
rtValue = pjp.proceed(args);//明确调用业务层方法(切入点方法)
System.out.println("后置代码位置");
return rtValue;
//注意Throwable t,使用Expention是不行的
}catch (Throwable t){
System.out.println("异常代码位置");
throw new RuntimeException(t);
}finally {
System.out.println("最终代码位置");
}
}
基于注解的Spring AOP
使用注解代替xml进行配置的时候,首先要做的就是告诉Spring我们使用了注解,还要告诉要扫描的包。
<!-- 配置spring创建容器时要扫描的包-->
<context:component-scan base-package="com"></context:component-scan>
<!-- 配置spring开启注解AOP的支持 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
使用**@Aspect**,表示当前类是一个切面类。相当于aop:aspect标签
@Before , @AfterReturning , @AfterThrowing , @After , @Around
分别就是前置,后置,异常,最终,环绕。在使用它们的时候需要传入表达式,跟使用xml时的表达式一样。
@Pointcut("execution(* com.service.impl.*.*(..))")
private void ex(){}
@Before("ex()")
也可以使用@Pointcut来配置表达式。
注意:使用xml配置的时候,通知的调用顺序是前置->后置(或异常)->最终
而使用@Before , @AfterReturning , @AfterThrowing , @After这4个注解的时候,
调用顺序是 前置->最终->后置(或异常)
所以,当使用注解的时候需要注意一点,可以考虑使用环绕通知来解决调用顺序的问题。

2000

被折叠的 条评论
为什么被折叠?



