Spring之基于注解@Aspect方式的Aop

1. AOP基础概念

AOP(Aspect-Oriented Programming)即面向切面编程,与我们熟悉的OOP面向对象变成不同,面向对象变成的基础单位为类:Class,通过继承、封装、多态等着力于构建一个垂直方向上的结构,强调类之间的层次,就像用Class一层层构建的高楼大厦,每个Class或对象就像大厦中的一个个房间。

但是,当我们想对大量房间装相同的新设备时就会非常麻烦,必须在每个Class中添加类似的代码以达到目的。这里,我们就引入了AOP面向切面编程的概念,还是前面比喻的大厦,假如我们想要为每个Class增加日志记录的功能,就像是为Class构建的大厦的房间中添加摄像头监控设备,按OOP的做法,就必须在所有的Class中添加类似的记录日志代码,但是利用AOP,我们更加关注横向,也即忽略不同Class的层次(继承等),将每个Class拆分为一个个joinpoint(在spring中指方法),也即将大厦拆分为一个个房间中更小的单位,可以统一为所有符合要求的房间安装一个总监控系统,而不用我们分别去每个房间安装设备。

  1. Aspect Aspect(切面)由pointcut(切点)和advise(增强)组成,pointcut描述了我们关注或者需要做advise的jointpoint(连接点),一起构成了Aspect(切面)的概念。
  2. joinpoint joinpoint(连接点),在spring中,joinpoint代表方法的执行点,所有的方法都可以认为是joinpoint。
  3. pointcut pointcut(切点),我们已经知道可以将所有的方法看作joinpoint,但是大多数时候我们不需要在所有的方法上(也即joinpoint)使用advise(增强),所以就需要对我们增强的目标点进行描述,而pointcut可以对增强目标进行描述、限定,例如制定对某个包中以service结尾的方法使用增强。需要注意的是,pointcut并不是一个特殊的joinpoint,而是一种描述或者定义,描述了哪些joinpoint需要进行增强。
  4. advise advise(增强),将advise代码织入目标joinpoint(即满足pointcut限定的joinpoint)中,在目标joinpoint执行前、后、抛出异常时调用我们的advise增强中对应的代码。

2. @AspectJ

@AspectJ是一种使用Java注解完成AOP的编码风格。与普通spring中利用xml方式配置AOP不同,@AspectJ 方式通过在AOP类上标注注解的方式完成AOP的配置。 下面简单介绍下在spring中如何使用@AspectJ 方式配置AOP:

  1. 引入支持@AspectJ的jar包: 在maven的配置文件中需要加入:
    <!--spring Aop-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <!--使用AspectJ方式注解需要相应的包-->
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjrt</artifactId>
      <version>${aspectj.version}</version>
    </dependency>
    <!--使用AspectJ方式注解需要相应的包-->
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>${aspectj.version}</version>
    </dependency>
复制代码
  1. spring配置支持@AspectJ : 在spring的xml配置文件中添加:
     <!-- 扫描aop包下所有使用注解的类型 -->
    <context:component-scan base-package="com.moyuzai.servlet.aop"/>

    <!--支持aspectj-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
复制代码

不要忘记添加aop的命名空间。

  1. 编写AOP类

首先我们编写一个日志增强类,对某些方法进行增强:在方法执行前打印出所执行方法的名称、参数等信息,在方法返回值后打印返回值,当有异常抛出时打印异常信息:

@Component
@Aspect
public class LogAdvise {

    Logger logger = LoggerFactory.getLogger(this.getClass());

    //within(com.moyuzai.servlet.controller.*)表示controller包下所有的连接点joinpoint都是pointcut,这里的joinpoint可以认为是所有的方法,
    // 而pointcut只是对符合我们想要增强(advise)的joinpoint的一种描述,描述什么样的joinpoint才是我们想要增强对象。
    @Pointcut("within(com.moyuzai.servlet.controller.*)")
    public void logPointCut(){

    }

    //增强(advise)
    @Before("logPointCut()")
    public void logMethodInvokeParam(JoinPoint joinPoint){
        logger.info("执行方法:{}, 参数:{}",joinPoint.getSignature().toShortString(),joinPoint.getArgs());
    }

    @AfterReturning(pointcut = "logPointCut()",returning = "retVal")
    public void logMethodInvokeResult(JoinPoint joinPoint,Object retVal){
        logger.info("方法:{} 的返回值:{}",joinPoint.getSignature().toShortString(),joinPoint.getArgs());
    }

    @AfterThrowing(pointcut = "logPointCut()",throwing = "exception")
    public void logMethodInvokeException(JoinPoint joinPoint,Exception exception){
        logger.info("方法:{}出现异常:{}",joinPoint.getSignature().toShortString(),exception.getMessage());
    }
}
复制代码

这样,当“com.moyuzai.servlet.controller”包下所有的方法得到执行的前后就会调用LogAdvise中的增强方法,起到了记录日志的作用。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值