27、AOP-AOP功能测试

AOP : 【动态代理】指程序运行期间动态的将某段代码切入到制定方法位置进行运行的编程方式。


  1. 导入AOP模块:Spring AOP(spring-aspects)
  2. 定义一个业务逻辑类(Mathcalculator);在业务逻辑运行的时候将日志进行打印(方法之前、方法运行之后等)
  3. 定义一个日志切面类(LogAspects):切面类里面的方法需要动态感知MathCalculator(div)运行到哪里,然后执行
  4. 方法通知:
    1. 前置通知(@Befor):LogStart
    2. 后置通知(@After):LogEnd
    3. 返回通知(@AfterReturning):LogReturn
    4. 异常通知(@AfterThrowing):LogException
    5. 环绕通知(@Aound):动态代理,手动推进目标方法运行(joinPoint.procced())
  5. 将切面类的目标犯法标注何时何地运行(通知注释);
  6. 将切面类和业务逻辑类(目标方法所在类 )加入到容器类;
  7. 配置类中@EnableAspectJAutoProxy 开启基于注解的AOP模式

27.1 Mathcalculator

package com.hw.springannotation.aop;

/**
 * @Description
 * @Author Administrator
 * @Date 2018/12/1
 */
public class MathCalculator {

    public int div(int i, int j) {
        System.out.println("MathCalculator   div 运行...");
        return i / j;
    }
}

27.2 LogAspects

package com.hw.springannotation.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

import java.util.Arrays;

/**
 * @Description
 * @Author Administrator
 * @Date 2018/12/1
 */
@Aspect // 告诉SPRING 当前类是一个切面类
public class LogAspects {

    @Pointcut("execution(public int com.hw.springannotation.aop.MathCalculator.*(..))")
    public void pointCut() {
    }

    @Before("pointCut()")
    public void logStart(JoinPoint joinPoint) {
        String methodName = joinPoint.getSignature().getName(); //方法名
        Object[] args = joinPoint.getArgs();    //参数列表
        System.out.println(methodName + "运行,参数列表是:{" + Arrays.asList(args) + "}");
    }

    @After("pointCut()")
    public void logEnd(JoinPoint joinPoint) {
        System.out.println(joinPoint.getSignature().getName() + "除法结束。。。");
    }

    @AfterReturning(value = "pointCut()", returning = "result")
    public void logReturn(JoinPoint joinPoint, Object result) {
        System.out.println(joinPoint.getSignature().getName() + "除法正常返回,运行结果是:" + result);
    }

    @AfterThrowing(value = "pointCut()", throwing = "exception")
    public void logException(JoinPoint joinPoint, Exception exception) {
        System.out.println(joinPoint.getSignature().getName() + "除法运行异常,异常信息:" + exception.getMessage());
    }

}

27.3 配置类 MainConfigOfAop

package com.hw.springannotation.config;

import com.hw.springannotation.aop.LogAspects;
import com.hw.springannotation.aop.MathCalculator;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

/**
 * @Description
 * @Author Administrator
 * @Date 2018/12/1
 */
@Configuration
@EnableAspectJAutoProxy
public class MainConfigOfAop {

    // 业务逻辑类加入到容器中
    @Bean
    public MathCalculator mathCalculator() {
        return new MathCalculator();
    }

    // 切面类 也加入到容器中
    @Bean
    public LogAspects logAspects() {
        return new LogAspects();
    }

}

27.4 测试用例

@Test
public void test() {

    // 不要自己创建对象
//        MathCalculator calculator = new MathCalculator();
//        calculator.div(1, 1);

    // 从容器中获取
    MathCalculator mathCalculator = applicationContext.getBean(MathCalculator.class);
    mathCalculator.div(1, 0);
    applicationContext.close();
}

运行:

注意:

  • JoinPoint joinPoint 参数一定要写在 参数位置的第一位