SpringAop

本文介绍了如何在Spring框架中进行AOP编程,包括编写接口、实现类、配置AOP切点和切面,以及使用@Before、@After、@AfterReturning和@Around注解来实现不同类型的Advice。最后展示了测试类如何使用SpringAOP进行集成。
摘要由CSDN通过智能技术生成

一、正常编写项目代码

1.编写接口

package com.suchuanlin.service;

public interface Calculator {
    int add(int i, int j);
    int sub(int i, int j);
    int mul(int i, int j);
    int div(int i, int j);
}

 2.编写实现类,实现接口

package com.suchuanlin.service.impl;

import com.suchuanlin.service.Calculator;
import org.springframework.stereotype.Component;

@Component
public class CalculatorImpl implements Calculator {
    @Override
    public int add(int i, int j) {
        int result = i + j;
        return result;
    }

    @Override
    public int sub(int i, int j) {
        int result = i - j;
        return result;
    }

    @Override
    public int mul(int i, int j) {
        int result = i * j;
        return result;
    }

    @Override
    public int div(int i, int j) {
        int result = i / j;
        return result;
    }
}

 3.编写配置文件

package com.suchuanlin.config;

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

@Configuration  //定义当前为配置类
@ComponentScan(value = "com.suchuanlin")  //定义注解包扫描范围
@EnableAspectJAutoProxy  //开启aspectj的注解
public class AppConfig {
}

 二、配置AOP

4.提取切点,统一管理

package com.suchuanlin.pointcut;

import org.aspectj.lang.annotation.Pointcut;

public class PointCutManager {

    @Pointcut("execution(* com.suchuanlin.service.impl.*.*(..))")
    public void servicePointCut(){}
}

 5.1编写切面类(@Before,@After,@AfterReturning,@AfterThrowing)

package com.suchuanlin.advice;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.junit.jupiter.api.Order;
import org.springframework.stereotype.Component;
import java.lang.reflect.Modifier;

@Component
@Aspect
@Order(10)
public class LogAdvice {
    @Before("com.suchuanlin.pointcut.PointCutManager.servicePointCut()")
    public void before(JoinPoint joinPoint){

        //1.获取方法所属的类的信息
        String simpleName = joinPoint.getTarget().getClass().getSimpleName();
        System.out.println("包信息:" + simpleName);
        //2.获取方法的修饰符
        int modifiers = joinPoint.getSignature().getModifiers();
        String string = Modifier.toString(modifiers);
        System.out.println("修饰符:" +string);
        //3.获取方法名
        String name = joinPoint.getSignature().getName();
        System.out.println("方法名:" + name);
        //4.获取参数列表
        Object[] args = joinPoint.getArgs();
        System.out.println("参数列表" + args);


        System.out.println("beginAdvice:核心代码执行前...");
    }

    @After("com.suchuanlin.pointcut.PointCutManager.servicePointCut()")
    public void after(){
        System.out.println("afterAdvice:核心代码执行后...");
    }

    @AfterReturning("com.suchuanlin.pointcut.PointCutManager.servicePointCut()")
    public void afterReturning(){
        System.out.println("afterReturningAdvice:核心代码返回值后...");
    }

    @AfterThrowing("com.suchuanlin.pointcut.PointCutManager.servicePointCut()")
    public void afterThrowing(){
        System.out.println("afterThrowingAdvice:核心代码抛出异常后...");
    }
}

5.2编写切面类(@Around)

package com.suchuanlin.advice;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.junit.jupiter.api.Order;
import org.springframework.stereotype.Component;

@Component
@Aspect
@Order(0)
public class AroundAdvice {

    @Around("com.suchuanlin.pointcut.PointCutManager.servicePointCut()")
    public Object aroundAdvice(ProceedingJoinPoint joinPoint){
        Object[] args = joinPoint.getArgs();
        Object result;
        try {
            //目标盘方法前执行
            System.out.println("aroundAdvice:目标方法前执行...");
            //调用目标方法
            result = joinPoint.proceed(args);
            System.out.println("aroundAdvice:目标方法返回后执行...");
        } catch (Throwable e) {
            System.out.println("aroundAdvice:目标方法抛异常时执行...");
            throw new RuntimeException(e);
        }
        finally {
            System.out.println("aroundAdvice:目标方法执行后执行...");
        }
        return result;
    }

}

三、测试

6.编写测试类

package com.suchuanlin.test;

import com.suchuanlin.config.AppConfig;
import com.suchuanlin.service.Calculator;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;

@SpringJUnitConfig(value = AppConfig.class)  //指定配置类
//@SpringJUnitConfig(locations = "classpath:spring-config.xml")  //指定配置文件路径
public class SpringAopTest {

    @Autowired
    private Calculator calculator;

    @Test
    public void test(){
        int add = calculator.add(1, 1);
        System.out.println("add = " + add);
    }
}

7.输出结果(注意:即使不设置@Order(0),@Around优先级最高,先进后出)

D:\Programs\Java\jdk-17\bin\java.exe...

aroundAdvice:目标方法前执行...
包信息:CalculatorImpl
修饰符:public abstract
方法名:add
参数列表[Ljava.lang.Object;@7b64240d
beginAdvice:核心代码执行前...
afterReturningAdvice:核心代码返回值后...
afterAdvice:核心代码执行后...
aroundAdvice:目标方法返回后执行...
aroundAdvice:目标方法执行后执行...
add = 2

Process finished with exit code 0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值