AOP(Annotation版)

  • Post author:
  • Post category:其他




什么是AOP


定义: 面向切面编程(面向方面编程)

咱们的编程语言从原始机器语言 到过程语言 再到面向对象,从始至终的目的就是为了让代码再加灵活,再加容易让人理解,构建代码更加简单。

面向对象的语言虽然已经非常优秀,但是在灵活性上总是有些不如人意,因此,现在出来了函数式编程,也出来了我们今天要给大家讲的AOP。而AOP的出来并不是要取代OOP(面向对象编程),它只是作为一个补充的角色过来,来解决一些咱们OOP解决不了(或者说很难解决)的一些代码。

AOP的使用只存在于一些特定的场合(具有横切逻辑的应用场合),横切逻辑这个解释可能比较抽象,咱们说得再具体一点,AOP可以用于事务管理,日志管理,性能监测等地方




AOP术语

连接点(Joinpoint):程序执行的某一个特定位置,如类初始前后,方法的运行前后。而Spring只支持方法的连接点。

切点(Pointcut):切点可以定位到相应的连接点,一个切点可以定位多个连接点。

增强(Advice):又被称为通知,完成逻辑的增强。

目标对象(Target):增强逻辑织入的目标类。

引介(Introduction):特殊的增强,为类添加一些属性和方法。

织入(Weaving): 将增强添加到目标类的具体连接点上的过程。Spring使用动态代理织入。

代理(Proxy):一个类(原类)被织入增强(逻辑)后,就产生一个结果类,称为代理类。

切面(Aspect):由切点和增强组成

AOP联盟:众多开源AOP项目的联合组织,该组织定义了一套规范描述AOP标准。现在大部分的AOP实现都是使用AOP实现的标准。



Spring的Aop

早期Spring是自己实现AOP,后期改回使用标准的aspects(面向切面编程)。那么咱们说过,Spring使用动态代理织入。

Spring支持我们在方法的前后添加增强代码。

Aop的功能作用Spring的两个核心之一,也可以是Spring非常重要的功能。

前面我们两次提到了一个概念:动态代理。是的,要想了解Spring怎么实现Aop,我们得了解动态代理。那么想要了解动态代理,咱们需要先来研究一下:代理模式。

如果是由咱们自己来完成动态代理确实是非常麻烦,不过好在大家并不用太过担心,因为Spring已经帮咱们把困难的部分完成,我们只需要做一些简单的配置就可以完成相应的功能。

配置的时候一定要记住三个要素:何时,何地,做什么事

何时:在执行方法之前/之后/有异常…

何地:在哪些包中的哪些类的哪些方法上面执行

做什么事: 在UserServie中执行update方法之前添加日志



Spring实现AOP的方案

Spring实现Aop有两种方案:JDK与CGLIB,这里我们以JDK版本为例

1.配置文件

<!-- 组件搜索 -->
<context:component-scan base-package="cn.itsource.aopanno" />
<!-- 支持aop注解 -->
<aop:aspectj-autoproxy />
<?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:context="http://www.springframework.org/schema/context"
       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/context
       http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd">
    <context:component-scan base-package="cn.itsource.SpringAopAnnotation"/>
    <aop:aspectj-autoproxy />
</beans>

2.事物管理器

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.test.annotation.Rollback;

@Component
@Aspect
public class AspectCurt {
//设置切点为service层下的所有文件所有类的所有方法
    @Pointcut("execution(* cn.itsource.SpringAopAnnotation.service..*.*(..))")
    public void aa() {
    }

    ;

//    @Before("aa()")前置通知
    private void Begin() {
        System.out.println("Begin");
    }

//    @After("aa()")最终通知
    public void Close() {
        System.out.println("Close");
    }

//    @AfterReturning("aa()")后置通知
    public void Commit() {
        System.out.println("Commit");
    }

//    @AfterThrowing("aa()")异常通知
    public void Throws() {
        System.out.println("Throws");

    }
//环绕通知
    @Around("aa()")
    public Object around(ProceedingJoinPoint joinPoint) {
        Object object = null;
        try {
            Begin();
            object = joinPoint.proceed();
            Commit();
        } catch (Exception e) {
            e.printStackTrace();
        } catch (Throwable throwable) {
            Throws();
        } finally {
            Close();
        }
        return object;
    }
}

在这里插入图片描述



版权声明:本文为qq_42572245原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。