【SSM_03】Spring-AOP

2021-02-04 10:49:13 浏览数 (1)

一、AOP概述

1. 什么是AOP
代码语言:javascript复制
* AOP是面向切面编程,在不修改代码的情况下,增强功能。
2. AOP的底层实现
代码语言:javascript复制
* JDK :通过接口实现
* CGlib :通过子类实现

# Spring 会根据目标类是否实现了接口来决定使用那种动态代理方式
3. AOP的相关概念
代码语言:javascript复制
* Target(目标对象):需要增强的对象
* Proxy(代理对象):被增强后的代理对象
* JoinPoint(接入点):有被增强资格的对象
* PointCut(切点):被增强的对象
* Advice(通知):增强的逻辑对象
* Aspect(切面):切点   通知
* Weaving(织入):增强的过程

二、XML实现动态代理

1. 配置
代码语言:javascript复制
<!-- 开启组件扫描 -->
<conext:component-scan base-package="com.softwareMan.aop" />

<!-- 将类的创建权交给spring容器 -->
<bean name="myAdvice" class="com.softwareMan.aop.MyAdvice" />
<bean name="target" class="com.softwareMan.aop.Target" />

<!-- 配置aop -->
<aop:config>
    <!-- 配置切面 -->
    <aop:aspect ref="myAdvice">
        <!-- 配置show方法的前置通知 -->
        <aop:after method="after" pointcut="execution(public void com.softwareMan.aop.Target.show())" />
    </aop:aspect>
</aop:config>
2. 配置详解
代码语言:javascript复制
① 通知种类
    - 前置通知            <aop:before>                 在切点方法执行前执行
    - 后置通知            <aop:after-returning>        在切点方法执行后执行
    - 环绕通知            <aop:around>                 在切点方法执行前后都执行
    - 异常抛出通知         <aop:throwing>               在抛出异常时执行
    - 最终通知            <aop:after>                  无论如何都会最后执行

    #环绕通知【对结果增强时使用】
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("环绕前增强....");
        Object proceed = pjp.proceed();//切点方法
        System.out.println("环绕后增强....");
        return proceed;
    }
    
② 切点表达式
    - [修饰] 返回值 方法全限定名(参数)
    - 修饰符可以省略,全限定名中使用 * 通配,..表示包含当前包下所有子包,参数中 .. 表示通配
    - 示例
        execution(* com.softwareMan.aop.*.*(..))
        execution(* com.softwareMan..*.*(..))
    - 切点表达式抽取
        <aop:aspect ref="myAdvice">
            <aop:pointcut id="myPointcut" expression="execution(* com.softwareMan.aop.*.*(..))"/>
            <aop:after method="after" pointcut-ref="myPointcut" />
        </aop:aspect>
        
③ 通知的配置
    <aop:通知类型 method="切面类中的增强方法" pointcut="切点表达式" />

三、注解实现

1. 注解的使用
代码语言:javascript复制
//切面类
@Component("myAdvice")
@Aspect
public class MyAdvice {
    //前置通知
    @Before("mypointcut()")
    public void before() {
        System.out.println("##########前置通知###########");
    }
    //后置通知
    @AfterReturning("mypointcut()")
    public void afterReturning() {
        System.out.println("##########后置通知###########");
    }
    //环绕通知
    @Around("mypointcut()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("##########环绕前置通知###########");

        Object proceed = pjp.proceed();

        System.out.println("##########环绕后置通知###########");

        return proceed;
    }
    //异常抛出通知
    @AfterThrowing("mypointcut()")
    public void afterThrowing() {
        System.out.println("##########异常抛出通知###########");
    }

    //最终通知
    @After("mypointcut()")
    public void after() {
           System.out.println("##########最终通知###########");
    }

    //抽取切点表达式
    @Pointcut("execution(* com.softwareMan.aop.*.*(..))")
    public void mypointcut(){}
}

//切点
@Component("terget")
public class Target implements TargetInterface {
    public void show() {
        System.out.println("show。。。。。。");
    }
}

# 注意开启 aop 自动代理 <aop:aspectj-autoproxy />
aop

0 人点赞