Spring的AOP

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个注解的时候,

​ 调用顺序是 前置->最终->后置(或异常)

所以,当使用注解的时候需要注意一点,可以考虑使用环绕通知来解决调用顺序的问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值