[[toc]]
# 实验一 初步实现

1、加入依赖

在IOC所需依赖基础上再加入下面依赖即可:


org.springframework
spring-aspects
5.3.1

2、准备被代理的目标资源

①接口

public interface Calculator {

  1. int add(int i, int j);
  2. int sub(int i, int j);
  3. int mul(int i, int j);
  4. int div(int i, int j);

}

②纯净的实现类

在Spring环境下工作,所有的一切都必须放在IOC容器中。现在接口的实现类是AOP要代理的目标类,所以它也必须放入IOC容器。
package com.atguigu.aop.imp;

import com.atguigu.aop.api.Calculator;
import org.springframework.stereotype.Component;

@Component
public class CalculatorPureImpl implements Calculator {

@Override<br />    public int add(int i, int j) {

    int result = i + j;

    System.out.println("方法内部 result = " + result);

    return result;<br />    }

@Override<br />    public int sub(int i, int j) {

    int result = i - j;

    System.out.println("方法内部 result = " + result);

    return result;<br />    }

@Override<br />    public int mul(int i, int j) {

    int result = i * j;

    System.out.println("方法内部 result = " + result);

    return result;<br />    }

@Override<br />    public int div(int i, int j) {

    int result = i / j;

    System.out.println("方法内部 result = " + result);

    return result;<br />    }<br />}

3、创建切面类

// @Aspect表示这个类是一个切面类
@Aspect
// @Component注解保证这个切面类能够放入IOC容器
@Component
public class LogAspect {

// @Before注解:声明当前方法是前置通知方法<br />    // value属性:指定切入点表达式,由切入点表达式控制当前通知方法要作用在哪一个目标方法上<br />    @Before(value = "execution(public int com.atguigu.aop.api.Calculator.add(int,int))")<br />    public void printLogBeforeCore() {<br />        System.out.println("[AOP前置通知] 方法开始了");<br />    }

@AfterReturning(value = "execution(public int com.atguigu.aop.api.Calculator.add(int,int))")<br />    public void printLogAfterSuccess() {<br />        System.out.println("[AOP返回通知] 方法成功返回了");<br />    }

@AfterThrowing(value = "execution(public int com.atguigu.aop.api.Calculator.add(int,int))")<br />    public void printLogAfterException() {<br />        System.out.println("[AOP异常通知] 方法抛异常了");<br />    }

@After(value = "execution(public int com.atguigu.aop.api.Calculator.add(int,int))")<br />    public void printLogFinallyEnd() {<br />        System.out.println("[AOP后置通知] 方法最终结束了");<br />    }

}

4、创建Spring的配置文件

<?xml version=”1.0” encoding=”UTF-8”?>
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance“ xmlns:aop=”http://www.springframework.org/schema/aop
xmlns:context=”http://www.springframework.org/schema/context
xsi:schemaLocation=”http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd”>

<!-- 开启基于注解的AOP功能 --><br />    <aop:aspectj-autoproxy/>

<!-- 配置自动扫描的包 --><br />    <context:component-scan base-package="com.atguigu.aop"/>

5、测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value = {“classpath:applicationContext.xml”})
public class AOPTest {

@Autowired<br />    private Calculator calculator;

@Test<br />    public void testAnnotationAOP() {

    int add = calculator.add(10, 2);<br />        System.out.println("方法外部 add = " + add);

}

}

打印效果如下:
[AOP前置通知] 方法开始了 方法内部 result = 12 [AOP返回通知] 方法成功返回了 [AOP后置通知] 方法最终结束了 方法外部 add = 12

6、通知执行顺序

  • Spring版本5.3.x以前:
    • 前置通知
    • 目标操作
    • 后置通知
    • 返回通知或异常通知
  • Spring版本5.3.x以后:
    • 前置通知
    • 目标操作
    • 返回通知或异常通知
    • 后置通知

回目录 下一个实验