Spring使用篇(七)—— 使用@AspectJ注解开发Spring AOP

本文详细介绍了如何使用@AspectJ注解在Spring中开发AOP,包括环境搭建、连接点选择、切面创建、切点定义、测试AOP、环绕通知、织入、传递参数以及引入等步骤,通过实例展示了Spring AOP的各个方面。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、开发环境搭建

  在Spring_Demo项目中创建名为“AspectJ”的module模块,并在lib文件夹中引入如下jar包,具体如下:
在这里插入图片描述
  然后在com.ccff.spring.aspectj.pojo包下创建名为“Role”的POJO类用于演示,具体代码如下所示:

package com.ccff.spring.aspectj.pojo;

public class Role {
   
    private Long roleId;
    private String roleName;
    private String roleNote;

    public Role() {
   
    }

    public Role(Long roleId, String roleName, String roleNote) {
   
        this.roleId = roleId;
        this.roleName = roleName;
        this.roleNote = roleNote;
    }

    public Long getRoleId() {
   
        return roleId;
    }

    public void setRoleId(Long roleId) {
   
        this.roleId = roleId;
    }

    public String getRoleName() {
   
        return roleName;
    }

    public void setRoleName(String roleName) {
   
        this.roleName = roleName;
    }

    public String getRoleNote() {
   
        return roleNote;
    }

    public void setRoleNote(String roleNote) {
   
        this.roleNote = roleNote;
    }

    @Override
    public String toString() {
   
        return "Role{" +
                "roleId=" + roleId +
                ", roleName='" + roleName + '\'' +
                ", roleNote='" + roleNote + '\'' +
                '}';
    }
}

2、选择连接点

  Spring是方法级别的AOP框架,而我们主要也是以某个类的某个方法作为连接点,用动态代理的理论来说,就是要拦截哪个方法织入对应AOP通知。为了更好的演示,首先在com.ccff.spring.aspectj.service包下创建名为“RoleService”的接口,具体代码如下:

package com.ccff.spring.aspectj.service;

import com.ccff.spring.aspectj.pojo.Role;

public interface RoleService {
   
    void printRole(Role role);
}

  这个接口十分简单,接下来为该接口提供一个名为“RoleServiceImpl”的实现类,具体代码如下:

package com.ccff.spring.aspectj.service;

import com.ccff.spring.aspectj.pojo.Role;
import org.springframework.stereotype.Component;

@Component
public class RoleServiceImpl implements RoleService {
   
    @Override
    public void printRole(Role role) {
   
        System.out.println(role.toString());
    }
}

  这个类没什么特别的,只是这个时候如果把printRole方法作为AOP的连接点,那么用动态地阿里的语言就是要为类RoleServiceImpl生成代理对象,然后拦截printRole方法,于是可以产生各种AOP通知方法。

3、创建切面

  选择好了连接点就可以创建切面了,对于动态代理的概念而言,它就如同一个拦截器在Spring中只要使用@Aspect注解一个类,那么Spring IoC容器就会认为这是一个切面了。在com.ccff.spring.aspectj.aspect包下创建名为“RoleAspect”的切面,并使用注解@Aspect注解这个类,具体代码如下:

package com.ccff.spring.aspectj.aspect;

import org.aspectj.lang.annotation.*;

@Aspect
public class RoleAspect {
   
    @Before("execution(* com.ccff.spring.aspectj.service.RoleServiceImpl.printRole(..))")
    public void before(){
   
        System.out.println("Before方法执行......");
    }

    @After("execution(* com.ccff.spring.aspectj.service.RoleServiceImpl.printRole(..))")
    public void after(){
   
        System.out.println("After方法执行......");
    }

    @AfterReturning("execution(* com.ccff.spring.aspectj.service.RoleServiceImpl.printRole(..))")
    public void afterReturning(){
   
        System.out.println("AfterReturning方法执行......");
    }

    @AfterThrowing("execution(* com.ccff.spring.aspectj.service.RoleServiceImpl.printRole(..))")
    public void afterThrowing(){
   
        System.out.println("AfterThrowing方法执行......");
    }
}

  上面的代码中并没有环绕通知,各个注解详细信息如下表所示:

注解 通知 备注
@Before 在被代理对象的方法前调用 前置通知
@Around 在被代理对象的方法封装起来,并用环绕通知取代它 环绕通知,它将覆盖原有方法,但是允许你通过反射调用原有方法,后续会讨论
@After 在被代理对象的方法后调用 后置通知
@AfterReturning 在被代理对象的方法正常返回后调用 返回通知,要求被代理对象的方法执行过程中没有发生异常
@AfterThrowing 在被代理对象的方法抛出异常后调用 异常通知,要求被代理对象的方法执行过程中发生异常

4、定义切点

  上一小节讨论了切面的组成,但是并没有详细讨论Spring是如何判断是否需要拦截方法的,毕竟并不是所有的方法都需要使用AOP编程,这就是一个确定连接点的问题。在切面中的注解定义了execution的正则表达式,Spring是通过这个正则表达式判断是否需要拦截你的方法的,这个表达式是:

execution(* com.ccff.spring.aspectj.service.RoleServiceImpl.printRole(..))

  依次对这个表达式做出分析:

  execution: 代表执行方法的时候会触发。

  *: 代表任意返回类型的方法。

  com.ccff.spring.aspectj.service.RoleServiceImpl:<

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值