Spring的AOP

1.概述:AOP(面向切面编程)是Spring的第二大核心思想,使用AOP思想可以在不修改业务代码的前提下,将一些与业务无关却是业务共同所调用的功能封装成一个"切面"模块,如:事务处理,日志管理以及权限控制。面向切面编程可以减少代码的冗余度并降低模块间的耦合度。

2.相关概念和通知类型

连接点(Join point):表示在程序中明确定义的点,典型的包括方法调用,异常处理程序块的执行,也就是所有的方法,不管是接口的抽象方法,还是实现类的重写方法。

切点(Pointcut):可能将抽取出来的共同功能添加的方法称为切点,切点是连接点的子集。

通知:抽取出来的共同功能称为通知,以通知在上下文的具体位置分类。

切面:即抽取出来的共同功能和切点,通知+切点。

目标对象(Target):切点所对应的类生成的对象,这种对象不能直接完成最终工作。

织入(Weaving):就是将通知添加到业务方法的过程。

通知的类型:

        (1)前置通知(Before):即在切点方法执行前执行。

        (2)返回通知(After-returning):切点方法正常执行完执行。

        (3)异常通知(After-throwing):切点方法发生异常时执行。

        (4)后置通知(After):也是切点方法执行完执行,执行位置相当于异常处理代码块中的finally代码块。

        (5)环绕通知(Aroud):可以发生在前四个通知的任意位置,其它通知的任意组合。  

3. 案例实现

SpringAop和Aspecj都是对AOP思想的实现,Aspectj的实现简单且方便,Spring框架中也整合了Aspectj技术。首先导入第三方jar包,下载地址:https://mvnrepository.com/artifact/org.aspectj/aspectjweaver

Maven坐标:

<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjweaver</artifactId>
  <version>1.9.7</version>
</dependency>

Calcuator类:

public class Calcuator {

    public int sum(int a,int b){
        System.out.println("业务方法执行中.....");
        return  a+b;
    }

    public int multi(int a,int b){
        System.out.println("业务方法执行中.....");
        return a*b;
    }
}

LoggerAspect类:

//日志切面类
public class LogggerAspect {
    
    //前置通知
    public void before(){
        System.out.println("【前置通知】=======>业务方法开始执行!!");
    }

    //返回通知
    public void afterReturning(){
        System.out.println("【返回通知】=======>业务方法执行结束!!");
    }

    //异常通知
    public void throwing(){
        System.out.println("【异常通知】========>业务方法出现异常!!");
    }

    //后置通知
    public void after(){
        System.out.println("【后置通知】========>业务方法最终执行结束!!");
    }
    
    //异常通知
    public Object aroundMethod(ProceedingJoinPoint joinPoint){
        Object result = null;
        try {
            System.out.println("【环绕通知】======>前置通知");
            result = joinPoint.proceed();
            System.out.println("【环绕通知】======>返回通知");
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            System.out.println("【环绕通知】======>异常通知");
        }finally {
            System.out.println("【环绕通知】======>后置通知");
        }
        return result;
    }
}

上面代码中,我们定义了两个类,一个为业务类进行整数计算,另一个为日志切面类,为每个业务方法添加日志功能,接下来,我们通过xml配置文件的方式进行配置。

<!--将类注入IOC容器-->
<bean id="calcuator" class="com.yyx.aop.Calcuator"/>

<bean id="logggerAspect" class="com.yyx.aop.LogggerAspect"/>

<!--设置aop-->
<aop:config>

     <!--设置切入点-->
     <aop:pointcut id="pointcut" expression="execution(public int com.yyx.aop.Calcuator.*(..))"/>
     <!--设置切面,id属性为唯一标识,ref属性引用切面类-->
     <aop:aspect id="main" ref="logggerAspect">
           <aop:before method="before" pointcut-ref="pointcut"/>
           <aop:after-returning method="afterReturning" pointcut-ref="pointcut"/>
           <aop:after-throwing method="throwing" pointcut-ref="pointcut"/>
           <aop:after method="after" pointcut-ref="pointcut"/>
      </aop:aspect>
</aop:config>

在配置文件中,第一步需要我们将业务类和切面类交给容器管理,然后通过<aop:config>标签配置aop,首先定义了pointCut切入点,表达式为execution(访问修饰符 返回值  包名.类名.方法名(参数列表)),最后在<aop:aspect>定义了通知的类型以及方法。

测试方法:

 运行结果:

 

注意事项: 

  切入点表达式:execution(访问修饰符 返回值  包名.类名.方法名(参数列表))

        1.访问修饰符可以省略,表示任意修饰符

                execution( 返回值  包名.类名.方法名(参数列表))

        2.返回值可以使用' * '通配符代替,表示任意类型

                execution(*  包名.类名.方法名(参数列表))

        3.包名可以使用' * '通配符代替,表示任意名称

                 execution(*  *.类名.方法名(参数列表))

        4.包名可以使用' .. '通配符代替,表示任意个数

                 execution(*  *...类名.方法名(参数列表)) 

        5.类名和方法名可以使用' * '通配符代替,表示任意名称

                  execution(*  *...*.*(参数列表)) 

        6.参数列表可以使用' .. '通配符代替,表示任意个数任意类型

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

                   如果需要指明参数: int ========>int,String====>java.lang.String,需要指定完全限定名,通常都只给业务层的所有方法配置aop。

4.环绕通知:

环绕通知可以是其它四个通知的任意组合,如果配置了环绕通知就不需要配置其它的通知了,配置方式如下:

<aop:config>
       <aop:pointcut id="pointcut" expression="execution(public int com.yyx.aop.Calcuator.sum(..))"/>
       <aop:aspect id="main" ref="logggerAspect">
               <aop:around method="aroundMethod" pointcut-ref="pointcut"/>
        </aop:aspect>
</aop:config>

运行结果: 

 如果需要使用注解配置aop,需要在配置文件中开启自动代理,然后在切面类上和方法上添加相应的注解即可。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值