栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

sping-aop(注解顶流方式)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

sping-aop(注解顶流方式)

想要使用spring中的任何技术 第一步都需要导包

第一步导包

  • spring核心包
  • spring整个aspectj
  • lombok偷懒神器
  • 测试包junit
  • spring集合junit4
    
        
            org.springframework
            spring-context
            5.3.9
        
        
            org.springframework
            spring-aspects
            5.2.5.RELEASE
        
        
            org.projectlombok
            lombok
            1.18.22
        
        
            junit
            junit
            4.13.1
            test
        
        
            org.springframework
            spring-test
            5.3.17
        
    

第二步 开始创建使用aop

  • 首先是创建spring的配置文件
  • 目的就是开启注解配置 包扫描



    

    

 创建一个目标对象

  • 目标对象解释:被通知的对象称之为目标对象

接口

public interface CalculatorDao {
    
    public int add(int a ,int b);

    
    public int sub(int a ,int b);
}

实现类

@Repository
public class CalucDaoImpl implements CalculatorDao {

    @Override
    public int add(int a, int b) {
        System.out.println("add-------------");
        return a+b;
    }

    @Override
    public int sub(int a, int b) {
        System.out.println("sub-------------");
        return a-b;
    }
}

创建切面

  • 名词解释 切面:非核心业务代码称之为:通知【提取到切面之后】
@Component
@Aspect
public class MyProxy {
    //加一个日志功能
    
    @Pointcut("execution(* com.cong.dao.impl.*.*(..))")
    public void myPorxy(){}

    
    @Before("myPorxy()")
    public void before(JoinPoint joinPoint){
        Signature signature = joinPoint.getSignature();
        String name = signature.getName();
        Object[] args = joinPoint.getArgs();
        System.out.println("前置通知 方法名是:"+name+"  参数是"+ Arrays.toString(args));
    }

    
    @After("myPorxy()")
    public void after(JoinPoint joinPoint){
        Signature signature = joinPoint.getSignature();
        String name = signature.getName();
        Object[] args = joinPoint.getArgs();
        System.out.println("后置通知 方法名是:"+name+"  参数是"+ Arrays.toString(args));
    }

    
    @AfterReturning(value = "myPorxy()",returning = "ret")
    public void afterReturning(JoinPoint joinPoint,Object ret){
        Signature signature = joinPoint.getSignature();
        String name = signature.getName();
        Object[] args = joinPoint.getArgs();
        System.out.println("返回通知 方法名是:"+name+"  参数是"+ Arrays.toString(args)+"   返回值是:"+ret);
    }

    
    @AfterThrowing(value = "myPorxy()",throwing = "e")
    public void afterReturning(JoinPoint joinPoint,Throwable e){
        Signature signature = joinPoint.getSignature();
        String name = signature.getName();
        Object[] args = joinPoint.getArgs();
        System.out.println("返回通知 方法名是:"+name+"  参数是"+ Arrays.toString(args));
    }

    
    @Around(value = "myPorxy()")
    public Object around(ProceedingJoinPoint proceedingJoinPoint){
        String name = proceedingJoinPoint.getSignature().getName();
        Object[] args = proceedingJoinPoint.getArgs();
        Object proceed = null;
        try {
            //前置通知
            System.out.println("前置通知 方法名是:"+name+"  参数是"+ Arrays.toString(args));
            proceed = proceedingJoinPoint.proceed();
            //返回通知
            System.out.println("返回通知 方法名是:"+name+"  参数是"+ Arrays.toString(args));
        } catch (Throwable e) {
            //异常通知
            System.out.println("返回通知 方法名是:"+name+"  异常是"+ e);
        } finally {
            //后置通知
            System.out.println("后置通知 方法名是:"+name+"  参数是"+ Arrays.toString(args));
        }


        return proceed;

    }
}

测试

@ContextConfiguration(locations = "classpath:applicationContext.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class MyTest {

    @Autowired
    private CalculatorDao calculatorDao;

    @Test
    public void before() {
        int add = calculatorDao.add(1, 2);
    }

    @Test
    public void after() {
        int sub = calculatorDao.sub(20, 2);
    }
}

这里 总结下

前置通知: 没什么可注意的 加一个参数 JoinPoint 这里可以获取类的签名

类的签名就是类名加参数 都可以获取到

注意的是在切点执行之前执行 所以有异常也会执行

 



 

 后置通知 

需要注意的是 后置通知是最后执行的 不管有没有异常都会执行

 



返回通知

这里返回通知就是可以有一个返回值

需要加一个参数

@AfterReturning(value = "myPorxy()",returning = "ret")

这个参数名字ret可以随便叫 你喜欢就行 但是必须和方法中的Object中的形参名形同

有异常不会执行

 



 异常通知

顾名思义就是有异常才会执行 没有异常不会执行

这里和返回通知同样有一个参数值 是异常类型的形参 可以随便叫什么名字



 

 前面四个通知有一个总结性的通知

叫做环绕通知  需要注意两点

第一点就是必须要有一个返回值类型 必须和目标方法返回值类型一直 用Object

第二点就是必须加一个参数

ProceedingJoinPoint 

执行方法

proceed = proceedingJoinPoint.proceed();

代表目标对象方法的执行  所以给他一个try catch finally

分别加上前置通知 返回通知 异常通知 和后置通知

 



 四个通知的执行流程

有异常的情况下 : 前置通知->异常->后置

无异常的情况下 : 前置 ->返回->后置

 

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/835951.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号