【Spring】AOP 面向切面编程-前置通知(掌握)

总结:
Aspectj表示切面执行时间,用的通知(Advice)。
这个通知可以使用注解表示。
5个注解表示切面的5个执行时间, 这些注解叫做通知注解

  • @Before : 前置通知
  • @AfterRetunring: 后置通知
  • @Around: 环绕通知
  • @AfterThrowing:异常通知
  • @After:最终通知

使用aspectj框架的注解,实现前置通知

前置通知@Before

实现步骤:

  1. 新建maven项目

  2. 修改pom.xml 加入依赖:
    spring-context依赖, spring-aspects依赖(能使用aspectj框架的功能),junit

  3. 创建业务接口和实现类。

  4. 创建一个叫做切面类,是一个普通类
    1)在类的上面加入@Aspect
    2) 在类中定义方法, 方法表示切面的功能。在方法的上面加入Aspect框架中的通知注解,例如@Before(value=“切入点表达式”)

  5. 创建spring配置文件。
    1)声明目标对象
    2)声明切面类对象
    3)声明自动代理生成器

  6. 创建测试类,测试目标方法执行时,增加切面的功能

具体实现

1.新建maven项目
在这里插入图片描述
👇
2.添加依赖:
在这里插入图片描述
3.创建业务接口—service包

public interface SomeService {
    //doSome模拟某一个操作
     void doSome(String name,Integer age);
}

4.实现这个接口-impl
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
5.添加功能—创建一个类叫做切面类,是一个普通类
1)在类的上面加入@Aspect
2) 在类中定义方法, 方法表示切面的功能。在方法的上面加入Aspect框架中的通知注解,例如@Before(value="切入点表达式")
在这里插入图片描述
@Aspect: 切面类的注解,表示当前类是切面类而已。

  • 位置:放在某个类的上面
  • 作用:表示当前类是切面类。

切面类:包含切面功能的类

@Aspect
public class MyAspact {

}

👇
前置通知方法的定义
1)方法是public
2)方法是void
3)方法名称自定义
4)方法可以有参数,如果有是JoinPoint,也可以没有

 public void myBefore(){
}

👇
@Before语法格式:

@Before(value = "切入点表达式")

特点:
1)执行时间:在目标方法之前先执行的。
2)不会影响目标方法的执行。
3)不会修改目标方法的执行结果。
👇
在这里插入图片描述
6.创建spring配置文件。
1)声明目标对象
2)声明切面类对象
3)声明自动代理生成器

差一个代理---->框架帮忙编写代理类完成SomeServiceImpl中的doSome功能----->Spring配置文件

创建Spring配置文件:
在这里插入图片描述
在这里插入图片描述
1)声明目标对象
2)声明切面类对象
3)声明自动代理生成器 <auto + Enter
👇👇👇

<!--声明目标对象-->
<bean id="someService" class="com.bjpowernode.service.impl.SomeServiceImpl" />

<!--声明切面类对象-->
<bean id="myAspect" class="com.bjpowernode.handle.MyAspect"  />

<!--声明自动代理生成器:
	目的是创建目标对象的代理(就是06项目中的ServiceProxy)
标签:调用aspectj框架中的功能, 寻找spring容器中的所有目标对象,
	把每个目标对象加入切面类中的功能, 生成代理。
这个代理对象是修改的内存中的目标对象, 这个目标对象就是代理对象(ServiceProxy)
-->
<aop:aspectj-autoproxy />

7.测试
没有加入代理的处理:
1)目标方法执行时,没有切面功能的。
2)service对象没有被改变
在这里插入图片描述
👇
在这里插入图片描述


加入代理的处理:
1)目标方法执行时,有切面功能的。
2)service对象是改变后的代理对象 com.sun.proxy.$Proxy8
前置通知在doSome()之前执行
在这里插入图片描述
在这里插入图片描述

以前手动写的:
在这里插入图片描述
表达式形式变化:
在这里插入图片描述
do*代表只要是do开头的方法都可以。

在业务接口中添加一个方法:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
切面类中的通知方法,可以有参数👉JoinPoint

JoinPoint: 表示正在执行的业务方法,相当于反射中的 Method
使用要求:必须是参数列表的第一个
作用:获取方法执行时的信息,例如方法名称, 方法的参数集合

@Before(value="execution(* *..SomeServiceImpl.do*(..))")
    public void myBefore(JoinPoint jp){

        //获取方法的定义
        System.out.println("前置通知中,获取目标方法的定义:"+jp.getSignature());
        System.out.println(" ");
        System.out.println("前置通知中,获取方法名称="+jp.getSignature().getName());
        System.out.println(" ");

        //获取方法执行时参数
        Object args []= jp.getArgs();// 数组中存放的是 方法的所有参数
        for(Object obj:args){
            System.out.println("前置通知,获取方法的参数:"+obj);
        }

        System.out.println(" ");
        //切面的代码
        System.out.println("===前置通知,切面的功能,在目标方法之前先执行==:"+ new Date());
        System.out.println(" ");
    }

在这里插入图片描述

@Before(value="execution(* *..SomeServiceImpl.do*(..))")
    public void myBefore(JoinPoint jp){

        //获取方法的定义
        System.out.println("前置通知中,获取目标方法的定义:"+jp.getSignature());
        System.out.println(" ");
        System.out.println("前置通知中,获取方法名称="+jp.getSignature().getName());
        System.out.println(" ");

        //获取方法执行时参数
        Object args []= jp.getArgs();// 数组中存放的是 方法的所有参数
        for(Object obj:args){
            System.out.println("前置通知,获取方法的参数:"+obj);
        }

        String methodName = jp.getSignature().getName();
        if("doSome".equals(methodName)){
            //切面的代码。
            System.out.println("doSome输出日志=====前置通知,切面的功能,在目标方法之前先执行==:"+ new Date());
        } else if("doOther".equals(methodName)){
            System.out.println("doOther前置通知,作为方法名称,参数的记录。");
        }

        System.out.println(" ");
        //切面的代码
        System.out.println("===前置通知,切面的功能,在目标方法之前先执行==:"+ new Date());
        System.out.println(" ");
    }

在这里插入图片描述
灵活处理不同的目标方法,不同的切面功能,灵活。
JoinPoint如果用就加,必须是参数第一个。

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值