Spring AOP 总结

1.简介

Spring AOP是Spring针对面向切面编程的落地方案,用于解决非核心代码的冗余问题。

Spring AOP只能运用于存于IoC容器中的对象。

2.知识

2.1 底层实现

Spring AOP框架针对不同情况有两种底层实现基于Jdk的动态代理和基于cglib:

  • 动态代理:用于有接口的类,采用继承接口的方式实现代理。
  • cglib:用于没有接口的类,采用继承子类的方式实现代理。

2.2 插入点

Spring AOP框架总共有5种插入点:

  • 前置通知@Before: 目标函数执行前执行
  • 返回通知@AfterReturning:目标函数执行后执行
  • 异常通知@AfterThrowing:catch中执行
  • 后置通知@After:finally中执行
  • 环绕通知@Around:包含上面所有通知节点,完全自定义

3.代码

要使用Spring AOP,必须加入以下组件到pom.xml中

xml 复制代码
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>6.0.6</version>
</dependency>

配置类中开启AOP

java 复制代码
@Configuration//声明这是一个配置类
@ComponentScan("com.jojo")//设置扫描范围
@EnableAspectJAutoProxy//开启AOP
public class JavaConfig {
}

切面增强类的编写:

java 复制代码
@Component//增强类必须放入IoC容器
@Aspect//声明切面
@Order(2)//设置优先级,值越小,优先级越高,前置先执行,后置后执行
public class LogAdvice {
    @Before("com.jojo.pointcut.MyPointCut.point()")
    public void before(JoinPoint joinPoint){//目标方法的封装对象
        //1.获取的类名
        String simpleName = joinPoint.getTarget().getClass().getSimpleName();
        //2.获取方法名称
        int modifiers = joinPoint.getSignature().getModifiers();
        String s = Modifier.toString(modifiers);//获取是public还是其他
        String name = joinPoint.getSignature().getName();//获取方法名
        //3.获取参数列表
        Object[] args = joinPoint.getArgs();//获取参数
    }

    @AfterReturning(value = "com.jojo.pointcut.MyPointCut.point()",returning = "result")//接受核心函数返回变量到result
    public void afterReturning(JoinPoint joinPoint, Object result){//设置返回变量

    }

    @After("com.jojo.pointcut.MyPointCut.point()")
    public void after(JoinPoint joinPoint){

    }

    @AfterThrowing(value = "execution(* com..impl.*.*(..))",throwing = "throwable")//接受异常信息到throwable
    public void afterThrowing(JoinPoint joinPoint,Throwable throwable){//设置异常信息变量

    }
    
    @Around("com.jojo.pointcut.MyPointCut.point()")//声明环绕通知
    public Object transaction(ProceedingJoinPoint joinPoint) throws Throwable {

        System.out.println("前置通知");//增强代码,前置通知
        Object[] args = joinPoint.getArgs();//目标参数获取
        System.out.println("返回通知");//增强代码,返回通知
        Object result = null;
        try {
            result = joinPoint.proceed(args);//目标函数调用
        } catch (Throwable e){
            System.out.println("异常通知");//增强代码,异常通知
            throw new RuntimeException(e);//抛出异常
        } finally{
        	System.out.println("后置通知");//增强代码,后置通知
        }
        return result;//目标方法的返回值
    }
}

插入点类的编写

java 复制代码
@Component
public class MyPointCut {
    @Pointcut("execution(* com.jojo.service.impl.*.*(..))")//插入点统一管理
    public void point(){}
}

测试:

java 复制代码
@SpringJUnitConfig(value = JavaConfig.class)//声明使用的配置类
public class SpringAopTest {
    @Autowired
    //针对有接口类必须使用接口而非接口实现类来声明
    //针对无接口类使用实现类来声明
    private MyTest myTest;


    @Test
    public void test(){
        int result = myTest.do(1);
        System.out.println("result = "+ result);
    }
}
相关推荐
填满你的记忆4 分钟前
Gemini使用教程
java·后端·ai编程
一只乔哇噻5 分钟前
java后端工程师+AI大模型开发进修ing(研一版‖day63)
java·开发语言·人工智能·python·语言模型
风月歌5 分钟前
小程序项目之使命召唤游戏助手源代码(java+vue+小程序+mysql)
java·mysql·小程序·毕业设计·源码
源代码•宸6 分钟前
goframe框架签到系统项目(安装 redis )
服务器·数据库·经验分享·redis·后端·缓存·golang
想不明白的过度思考者12 分钟前
Java网络聊天室——OverThinker-ChatRoom
java·开发语言·网络
漂亮的小碎步丶13 分钟前
【4】Spring Boot项目中Spring核心容器原理详解
java·后端·spring
过期动态14 分钟前
JDBC进阶篇:拓展功能与连接池运用详解
java·开发语言·数据库·mysql·oracle·intellij-idea·mybatis
applebomb14 分钟前
经济、能打的vibe coding后端组合:IDEA+Claude Code(WSL)+GLM4.6安装与配置
java·idea·ai编程·vibecoding
❥ღ Komo·2 小时前
K8s服务发现与DNS解析全解析
java·开发语言
g***B7384 小时前
Java 工程复杂性的真正来源:从语言设计到现代架构的全链路解析
java·人工智能·架构