SSM - Springboot - MyBatis-Plus 全栈体系(十一)

第二章 SpringFramework

五、Spring AOP 面向切面编程

6. Spring AOP 基于 XML 方式实现(了解)

6.1 准备工作
  • 加入依赖
  • 和基于注解的 AOP 时一样。
  • 准备代码
  • 把测试基于注解功能时的 Java 类复制到新 module 中,去除所有注解。
6.2 配置 Spring 配置文件
<!-- 配置目标类的bean -->
<bean id="calculatorPure" class="com.alex.aop.imp.CalculatorPureImpl"/>

<!-- 配置切面类的bean -->
<bean id="logAspect" class="com.alex.aop.aspect.LogAspect"/>

<!-- 配置AOP -->
<aop:config>

    <!-- 配置切入点表达式 -->
    <aop:pointcut id="logPointCut" expression="execution(* *..*.*(..))"/>

    <!-- aop:aspect标签:配置切面 -->
    <!-- ref属性:关联切面类的bean -->
    <aop:aspect ref="logAspect">
        <!-- aop:before标签:配置前置通知 -->
        <!-- method属性:指定前置通知的方法名 -->
        <!-- pointcut-ref属性:引用切入点表达式 -->
        <aop:before method="printLogBeforeCore" pointcut-ref="logPointCut"/>

        <!-- aop:after-returning标签:配置返回通知 -->
        <!-- returning属性:指定通知方法中用来接收目标方法返回值的参数名 -->
        <aop:after-returning
                method="printLogAfterCoreSuccess"
                pointcut-ref="logPointCut"
                returning="targetMethodReturnValue"/>

        <!-- aop:after-throwing标签:配置异常通知 -->
        <!-- throwing属性:指定通知方法中用来接收目标方法抛出异常的异常对象的参数名 -->
        <aop:after-throwing
                method="printLogAfterCoreException"
                pointcut-ref="logPointCut"
                throwing="targetMethodException"/>

        <!-- aop:after标签:配置后置通知 -->
        <aop:after method="printLogCoreFinallyEnd" pointcut-ref="logPointCut"/>

        <!-- aop:around标签:配置环绕通知 -->
        <!--<aop:around method="……" pointcut-ref="logPointCut"/>-->
    </aop:aspect>

</aop:config>
6.3 测试
@SpringJUnitConfig(locations = "classpath:spring-aop.xml")
public class AopTest {

    @Autowired
    private Calculator calculator;

    @Test
    public void testCalculator(){
        System.out.println(calculator);
        calculator.add(1,1);
    }
}

7. Spring AOP 对获取 Bean 的影响理解

7.1 根据类型装配 bean
7.1.1 情景一
  • bean 对应的类没有实现任何接口

  • 根据 bean 本身的类型获取 bean

    • 测试:IOC 容器中同类型的 bean 只有一个

      正常获取到 IOC 容器中的那个 bean 对象

    • 测试:IOC 容器中同类型的 bean 有多个

      会抛出 NoUniqueBeanDefinitionException 异常,表示 IOC 容器中这个类型的 bean 有多个

7.1.2 情景二
  • bean 对应的类实现了接口,这个接口也只有这一个实现类
    • 测试:根据接口类型获取 bean
    • 测试:根据类获取 bean
    • 结论:上面两种情况其实都能够正常获取到 bean,而且是同一个对象
7.1.3 情景三
  • 声明一个接口

  • 接口有多个实现类

  • 接口所有实现类都放入 IOC 容器

    • 测试:根据接口类型获取 bean

      会抛出 NoUniqueBeanDefinitionException 异常,表示 IOC 容器中这个类型的 bean 有多个

    • 测试:根据类获取 bean

      正常

7.1.4 情景四
  • 声明一个接口

  • 接口有一个实现类

  • 创建一个切面类,对上面接口的实现类应用通知

    • 测试:根据接口类型获取 bean

      正常

    • 测试:根据类获取 bean

      无法获取

  • 原因分析:

    • 应用了切面后,真正放在 IOC 容器中的是代理类的对象
    • 目标类并没有被放到 IOC 容器中,所以根据目标类的类型从 IOC 容器中是找不到的

在这里插入图片描述

7.1.5 情景五
  • 声明一个类
  • 创建一个切面类,对上面的类应用通知
    • 测试:根据类获取 bean,能获取到

在这里插入图片描述

  • debug 查看实际类型:

在这里插入图片描述

7.2 使用总结
  • 对实现了接口的类应用切面
    在这里插入图片描述
  • 对没实现接口的类应用切面 new
    在这里插入图片描述
  • 如果使用 AOP 技术,目标类有接口,必须使用接口类型接收 IoC 容器中代理组件!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柠檬小帽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值