AspectJ实现AOP

AOP 是面向切面编程的编程思想,AOP 解决日志、权限等于横切性问题,将这些问题与主业务逻辑分开,达到与主业务逻辑结构的目的。

当我们在编写程序的时候,需要完成一些与核心业务逻辑无关的功能。比如说日志功能、权限校验功能。这些操作与对象的核心功能无关,并且散落在各种业务逻辑之中。我们将日志、权限控制这样的功能抽离成独立的切面,并在程序中设置连接点使用这些功能,这就是 AOP 的思想。

AOP 概念是 OOP(Object Oriented Programming) 概念的补充,我们使用面向对象的思想将程序的操作单位从函数变成了对象。但是面向对象的思想,面对与对象的核心功能无关的操作时显得很无力。AOP 的思想就能很优雅地处理这些散落在业务代码中的功能。

总的来说 OOP 思想关注纵向的业务逻辑,AOP 思想关注横向的功能扩展。两者相辅相成,互为补充。

补充:廖雪峰的教程中,关于 OOP 的描述,有一些比较经典。

OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。

面向过程的程序设计把计算机程序视为一系列的命令集合,即一组函数的顺序执行。为了简化程序设计,面向过程把函数继续切分为子函数,即把大块函数通过切割成小块函数来降低系统的复杂度。

而面向对象的程序设计把计算机程序视为一组对象的集合,而每个对象都可以接收其他对象发过来的消息,并处理这些消息,计算机程序的执行就是一系列消息在各个对象之间传递。

… 面向对象的抽象程度又比函数要高,因为一个Class既包含数据,又包含操作数据的方法。

AOP 的应用场景

  1. 日志记录
  2. 权限验证
  3. 效率检查
  4. 事务管理
  5. exception

Spring Aop 和 AspectJ 的关系

AOP 是一种概念

Spring Aop、AspectJ 都是 AOP 思想的具体实现,Spring Aop有自己的语法,但是语法复杂,所以 Spring Aop 借助了AspectJ的注解,但是底层实现还是自己的。

Spring AOP 提供两种编程风格:

  • 利用 aspectj 的注解@AspectJ support
  • xml aop:config 命名空间,Schema-based AOP support

本文第一章节演示的就是基于注解的方式。

AOP 相关概念

https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#aop-introduction-defn

  • Aspect: 切面,@Componet@Aspect 注解的
  • Pointcut: 切点,是连接点(JoinPoint)的集合,是一个方法
  • Joinpoint: 连接点,目标对象的方法,也就是我们需要关注和增强的方法 @Pointcut("execution(* *..test*())")
  • Advice:通知,位置 + 逻辑
  • Introduction
  • Target object:目标对象,原始对象,区别于经过 AOP 增强的对象
  • AOP prox:代理对象,包含了原始对象的代码和增加后的代码的那个对象
  • Weaving:织入,把代理逻辑加入到目标对象上的过程叫做织入

@AspectJ 实战 AOP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/**
 * 1. 申明是一个配置类:
 * 2. 配置扫描的包
 * 3. 开启对 AspectJ 的支持
 **/
@Configuration
@ComponentScan("com")
@EnableAspectJAutoProxy
public class AppConfig {

}

/**
 * 这是目标类,用 @Repository 将其交由 Spring 管理 
 **/
@Repository
public class IndexDao {
    public void test() {
        System.out.println("test");
    }
}

/**
 * @Component 要将类交给 Spring 进行管理
 * 其次要用 @Aspect 表明使用 AspectJ
 * 这个类就是一个 Aspect 切面
 **/
@Component
@Aspect
public class MyAspectJ {

    /**
     * 在切面里面定义方法,这个方法就是——Pointcut 切点
     *
     * 切点是由多有个 JoinPoint(连接点) 构成的
     *
     * 连接点就用 pointcut expressions 来表明的
     * 如:execution(* com.shuiyujie.dao...(..)) 具体可以去文档中找
     */
    @Pointcut("execution(* *..test*())")
    public void pointCut(){

    }


    /**
     * 最后就是设置 Advice 通知了:
     * 通知包括两部分,location 通知的位置;logic 通知的内容
     * @Before("pointCut()") 表示 location,在这个切点之前的位置
     * public void before() 这个方法就是logic,表示通知的内容
     */
    @Before("pointCut()")
    public void before(){
        System.out.println("before");
    }


}
posted @ 2018-03-05 07:09  深页  阅读(56)  评论(0编辑  收藏  举报