小言_互联网的博客

一篇了解什么是Spring AOP

477人阅读  评论(0)

AOP概述

AOP(Aspect Orient Programming)是一种设计思想,是软件设计领域中的面向切面编程,它是面向对象编程(OOP)的一种补充和完善。它以通过预编译方式和运行期动态代理方式,实现在不修改源代码的情况下给程序动态统一添加额外功能的一种技术。如图-1所示:

AOP与OOP字面意思相近,但其实两者完全是面向不同领域的设计思想。实际项目中我们通常将面向对象理解为一个静态过程(例如一个系统有多少个模块,一个模块有哪些对象,对象有哪些属性),面向切面的运行期代理方式,理解为一个动态过程,可以在对象运行时动态织入一些扩展功能或控制对象执行。

AOP 应用场景分析

实际项目中通常会将系统分为两大部分,一部分是核心业务,一部分是非核业务。在编程实现时我们首先要完成的是核心业务的实现,非核心业务一般是通过特定方式切入到系统中,这种特定方式一般就是借助AOP进行实现。

AOP就是要基于OCP(开闭原则),在不改变原有系统核心业务代码的基础上动态添加一些扩展功能并可以"控制"对象的执行。例如AOP应用于项目中的日志处理,事务处理,权限处理,缓存处理等等。如图-2所示:

AOP 应用原理分析

Spring AOP底层基于代理机制实现功能扩展:

1)假如目标对象(被代理对象)实现接口,则底层可以采用JDK动态代理机制为目标对象创建代理对象(目标类和代理类会实现共同接口)。
2)假如目标对象(被代理对象)没有实现接口,则底层可以采用CGLIB代理机制为目标对象创建代理对象(默认创建的代理类会继承目标对象类型)。
Spring AOP 原理分析,如图-3所示:

AOP 相关术语分析

切面(aspect): 横切面对象,一般为一个具体类对象(可以借助@Aspect声明)。
通知(Advice):在切面的某个特定连接点上执行的动作(扩展功能),例如around,before,after等。
连接点(joinpoint):程序执行过程中某个特定的点,一般指被拦截到的的方法。
切入点(pointcut):对多个连接点(Joinpoint)一种定义,一般可以理解为多个连接点的集合。
连接点与切入点定义如图-4所示:

说明:我们可以简单的将机场的一个安检口理解为连接点,多个安检口为切入点,安全检查过程看成是通知。总之,概念很晦涩难懂,多做例子,做完就会清晰。先可以按白话去理解。

AOP实现步骤

公式:AOP=(切面)=通知方法(5种)+切入点表达式(4种)

通知方法

1.@before通知------->在执行目标方法之前执行
2.@after通知------->在执行目标方法之后执行
3.@afterReturning通知------->无论什么时候程序执行完成之后都要执行的通知
4.@afterThrowing通知------->在目标方法执行之后报错时执行
(上述四大类型通知,不能控制目标方法是否执行。一般用来记录程序的执行状态。一般应用与监控的操作。(不改变程序运行的轨迹)
5.@around通知-------> 在目标方法执行前后执行
(环绕通知可控制目标方法是否执行,控制程序的执行的轨迹

切入点表达式

1.@bean(“beanId”) -------> bean:交给spring容器管理的对象,粒度:粗粒度 按bean匹配 当前bean中的方法都会执行通知
2.@within(“包名.类名”) ------->粒度:粗粒度 可以匹配多个类
3.@execution("返回值类型 包名.类名.方法名(参数列表)-------> 细粒度:方法参数级别
4.@annotation(“包名.类名”) ------->细粒度:按照注解匹配

package com.jt.aop;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component//交给spring容器管理
public class CacheAOP {
   
    //@Pointcut("bean(itemCatServiceImpl)")
    //@Pointcut("within(com.jt.service.ItemCatServiceImpl)")
    //@Pointcut("within(com.jt.service.*)")//.*一级包目录,..*所有子孙后代
    @Pointcut("execution(* com.jt.service..*.add*(..))")
    public void pointCut(){
   

    }

    @Before("pointCut()")
    public void before(){
   
        System.out.println("我是before通知");
    }
}


转载:https://blog.csdn.net/qq_45273552/article/details/110390512
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场