springBoot使用注解整合Aop实例介绍

Aop:面向切面编程,即是横向重复、纵向抽取思想。

springAop:底层封装了动态代理和cglib代理的代码,我们不需要手写动态代理的代码,封装的两个代理可以对任何类进行增强。

使用Aop的注意事项/坑:
1)、不宜把重要业务放在Aop中处理。
2)、Aop不处理Static、final、private方法
3)、无法拦截内部方法调用

spring名词:
1)连接点(JoinCut):目标对象中所有可以增强的方法,可以认为是类中的所欲方法

2)切入点(PointCut):目标对象中需要对它进行增强的方法

3)切面(Aspect):切入点+通知

4)织入(Weaving):将通知织入到切入点的过程叫做织入

5)目标对象(Target):即是需要增强的类

6)代理(Proxy):将通知织入到目标对象之后生成代理对象

7)通知/增强(Advice):对切入点所增强的代码

 

通知类型:

前置通知:(在调用目标对象之前执行)

环绕通知:(在目标对象调用之前和调用之后都会执行)

异常通知:(在调用目标对象之后执行)

后置通知(出现异常也会执行):(在调用目标对象之后异常情况下也会执行)

后置通知(出现异常不会执行):(在调用目标对象之后异常情况下不会执行)

 

springBoot整合Aop实例介绍

1、导入依赖 

<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2、设置方法接口

package com.ltj.demo.Service.Interface;


/**
 * 接口测试类
 */
public interface interfaceA {

    //增加
    public String save(int args1,int args2);

}

3、实现接口

package com.ltj.demo.Service;

import com.ltj.demo.Service.Interface.interfaceA;
import org.springframework.stereotype.Service;


/**
 * 设置通知
 */

@Service
public class interfaceAImpl implements interfaceA {

    @Override
    public String save(int mathScore,int engScore) {
        System.out.println("保存成功");
        System.out.println("the total score is : " + mathScore+engScore);
        return "保存成功22";
    }

}

4、设置通知类

package com.ltj.demo.Service;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/**
 * 通知/增强名词
 *      前置通知(在调用目标对象之前执行)
 *      后置通知(异常情况下不会执行)
 *      环绕通知(在目标对象调用之前和调用之后都会执行)
 *      异常通知(在调用目标对象之后执行)
 *      后置通知(异常情况下也会执行)
 */

/**
 * @Aspect:该注解设置该类为切面
 * @Component
 */
@Aspect
@Component
public class MyAdvice {

    //设置方法作为切入点
    @Pointcut(value = "execution(* com.ltj.demo.Service.interfaceAImpl.*(..))")
    public void pointCut(){}

    //设置前置通知
    @Before("MyAdvice.pointCut()")
    public void before(JoinPoint joinPoint){
        Object[] obj = joinPoint.getArgs();             //获取连接点方法运行时的入参列表
        String methodName = joinPoint.getSignature().getName();
        Object paramter1 = joinPoint.getSignature().getDeclaringType();
        Object paramter2 = joinPoint.getSignature().getDeclaringTypeName();
        Object paramter3 = joinPoint.getSignature().getModifiers();

        System.out.println(methodName);                     //获取目标对象的方法名
        System.out.println(paramter1);
        System.out.println(paramter2);
        System.out.println(paramter3);

        System.out.println(joinPoint.getThis());                                    //获取代理对象本身
        System.out.println(joinPoint.getTarget());                                  //获取连接点所在的目标对象

        for (Object objs: obj) {                //循环获取入参值
            System.out.println("入参:" + objs);
        }
        System.out.println("我是前置通知");
    }

    /**
     * 设置后置通知(异常情况下也会执行)
     * @param joinPoint 目标类连接点对象
     */
    @After("MyAdvice.pointCut()")
    public void after(JoinPoint joinPoint){
        System.out.println("设置后置通知(异常情况下也会执行)");
    }

    //设置后置通知(异常情况下不会执行)
    @AfterReturning(value="MyAdvice.pointCut()", returning ="results")      //value设置切入点,results为返回值
    public void afterReturn(JoinPoint joinPoint,Object results){            //results设置参数接收返回值

        System.out.println("设置后置通知(异常情况下不会执行)");

        System.out.println("返回值为:" + results);          //输出results返回值,即是目标对象的返回值
    }

    /**
     * 设置异常通知
     * @param proceedingJoinPoint   JoinPoint的子接口
     */
    @AfterThrowing("MyAdvice.pointCut()")
    public void afterThrow(ProceedingJoinPoint proceedingJoinPoint){
        System.out.println("我是异常通知");
    }

    /**
     * 设置环绕通知
     * @param proceedingJoinPoint   JoinPoint的子接口
     */
    @Around("MyAdvice.pointCut()")
    public void around(ProceedingJoinPoint proceedingJoinPoint){
        String methodName = proceedingJoinPoint.getSignature().getName();
        Object result = null;
        try {
            System.out.println("我是环绕通知");
            result = proceedingJoinPoint.proceed();                 //通过反射执行目标对象的连接点处的方法
            System.out.println("环绕通知的名称为:" + methodName +
                    ",返回的执行结果是:" + result);
        }catch (Throwable throwable){
            throwable.printStackTrace();
            System.out.println("异常返回");
        }
    }
}

5、使用测试类进行测试

package com.ltj.demo.Service;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import static org.junit.Assert.*;

@SpringBootTest
@RunWith(SpringRunner.class)
public class interfaceAImplTest {

    //自动注入
    @Autowired
    interfaceAImpl interfaceAImp;

    @Test
    public void example() {
        //调用保存方法
        interfaceAImp.save(1,2);
    }

}

友情链接:

AspectJ JoinPoint及ProceedingJoinPoint 简要api文档:https://blog.csdn.net/airjordon/article/details/83623830

SpringBoot集成ApringAOP:https://www.cnblogs.com/zdj-/p/8665454.html

springAop视同注解实现5种通知类型:https://www.cnblogs.com/fengxiangyu/p/10896547.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值