springAop原理

一、什么是AOP

AOP是对OOP(面向对象)的补充,OOP是自上而下的将程序抽象成各个层次的对象
而AOP是定义好切入点,只要被这些切入点包含的,都要执行AOP的通知。
(就是多个对象的方法执行前后会触发相同的一些逻辑,可以将这些逻辑提取出来)。

springAop原理_第1张图片

二、为什么需要 AOP

相同的逻辑也可以抽取成公共方法,然后要调用的时候在各个不同的类里面调用。
但是万一以后又要加一些其它的公共方法,那就要每个类里面都去加。
像这种统一逻辑的处理,完全可以用AOP解决,利用aop在这些方法执行前后加一些公共的逻辑
即可,实际上就是动态代理模式。

三、AOP 实现分类

AOP 要达到的效果是,保证开发者不修改源代码的前提下,去为系统中的业务组件添加某种通用功能(动态代理模式)。

静态 AOP 实现, AOP 框架在编译阶段对程序源代码进行修改,
生成了静态的 AOP 代理类(生成的 *.class 文件已经被改掉了,需要使用特定的编译器),比如 AspectJ。

动态 AOP 实现, AOP 框架在运行阶段对动态生成代理对象
(在内存中以 JDK 动态代理,或 CGlib 动态地生成 AOP 代理类),如 SpringAOP。

四、AOP术语和流程

1、通知(Advice):

就是代理方法,为目标方法(连接点)在执行前后添加一些特殊逻辑

通知分为前置、后置、异常、最终、环绕通知五类。


前置通知(Before):在目标方法被调用之前调用通知功能
后置通知(After):在目标方法完成之后调用通知,此时不会关心方法的输出是什么
环绕通知(Around):通知包裹了被通知的方法,在被通知的方法调用之前和之后执行自定义的行为。
返回通知(After-returning):在目标方法成功执行之后调用通知
异常通知(After-throwing):在目标方法抛出异常后调用通知

2、连接点(Join point)

被拦截到的点,因为Spring只支持方法类型的连接点,实际上就是目标方法

3、切点(Pointcut)

切点就是指定那些地方要被拦截到,定义了“何处”执行通知(代理方法)

4、切面(Aspect)

相当于一个拦截器配置类,定义一个切面,这个切面里面去定义通知、切点等。

5、织入(Weaving)

在织入切面时,AOP容器会为目标对象动态的创建一个代理对象,也就是动态代理。

6、流程说明:

@Aspect
@Order(-1)  // 该切面应当先于 @Transactional 执行
@Component
public class DynamicDataSourceAspect {


    /**
     * 前置通知,进入切点之前,先切换数据源。
     * @param point
     * @param targetDs
     */
    @Before("@annotation(targetDs)")
    public void switchDataSource(JoinPoint point, TargetDs targetDs) {
        //判断,如果没有此数据源
        if (!DynamicDataSourceContextHolder.containDataSourceKey(targetDs.value())){
            System.out.println("没有找到key为[{}]的数据源,所以当前还是使用默认数据源!"+targetDs.value());
        }else {
            DynamicDataSourceContextHolder.setDataSourceKey(targetDs.value());
            System.out.println("方法"+point.getSignature().getName()+"上发现@TargetDs注解,"+"当前数据源已经切换为[{}]!"+targetDs.value());
        }
    }
}


<1>、定义一个切面,也就是一个配置类用@Aspect标注。

<2>、定义通知,也就是代理方法,指定好切点,也就是在遇到什么方法之后才执行代理方法。

@Before("@annotation(targetDs)"):

定义通知,类型为前置通知@Before,定义切点为带有targetDs注解的方法,
这里也可以用方法名扫描的方式来定义切点。

springAop原理_第2张图片

<3>、JoinPoint point就是连接点,被拦截到的点,也就是目标方法

<4>、当执行到对应切点的时候,就会自动执行对应的通知里面的逻辑。

五、Spring对AOP的支持

AOP代理由spring容器生成和管理,所以在AOP切面中,可以随意使用和注入其它的springBean。

spring默认使用JDK动态代理来实现AOP代理,这样就可以为任何实现了接口的对象生成代理对象。
当要代理的对象没有实现任何接口的时候,spring会自动切换到Cglib的方式生成代理对象

AOP编程其实是很简单的事情,纵观AOP编程,程序员只需要参与三个部分:


1、定义普通业务组件(目标对象)

2、定义切入点,一个切入点可能横切多个业务组件(多个目标对象)

3、定义通知(代理方法),在AOP框架为普通业务组件(目标对象)生成代理对象,执行目标对象方法的时候就自动执行通知(代理方法)的逻辑。

你可能感兴趣的:(spring)