Spring AOP

Spring AOP

面向切面编程,是一个抽象化的面向对象编程,是对面向对象的一种补充。底层采用动态代理的机制。常用来

  • 打印日志
  • 事务
  • 权限处理

以打印日志为例

现有一个计算机Cal接口,需要在实现类CalImpl中打印日志,打印方法的参数已经方法的结果信息。

Cal

public interface Cal {
    // 加
    int add(int num1,int num2);
    // 减
    int sub(int num1,int num2);
    // 乘
    int mul(int num1,int num2);
    // 除
    int div(int num1,int num2);
}

CalImpl

public class CalImpl implements Cal {
    @Override
    public int add(int num1, int num2) {
        System.out.println("add的方法参数为:" + num1 + "," + num2);
        int result = num1 + num2;
        System.out.println("add方法的结果为:" + result);
        return result;
    }

    @Override
    public int sub(int num1, int num2) {
        System.out.println("sub的方法参数为:" + num1 + "," + num2);
        int result = num1 - num2;
        System.out.println("sub方法的结果为:" + result);
        return result;
    }

    @Override
    public int mul(int num1, int num2) {
        System.out.println("mul的方法参数为:" + num1 + "," + num2);
        int result = num1 * num2;
        System.out.println("mul方法的结果为:" + result);
        return result;
    }

    @Override
    public int div(int num1, int num2) {
        System.out.println("div的方法参数为:" + num1 + "," + num2);
        int result = num1 / num2;
        System.out.println("div方法的结果为:" + result);
        return result;
    }
}

在此方法中,日志和业务混合在一起,AOP要做的就是将日志代码全部抽象出去进行处理,计算器方法中只保留核心的业务代码。做到核心业务代码和非业务代码的解耦合。

使用AOP实现

在方法执行前切打一个切面,在方法的结束前打一个切面,用来打印日志信息
在这里插入图片描述

具体实现

1、导包

<!--aspect-->
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
    <version>1.9.7</version>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.7</version>
</dependency>

2、创建切面类(Aspect)

@Component
@Aspect // 表示是一个切面类
public class CalAspect {
    /**
     * 方法结束之前执行
     * @param joinPoint 连接点,获取连接的方法的参数等信息
     */
    @Before(value = "execution(public int com.demo.aop.CalImpl.*(..))")
    public void before(JoinPoint joinPoint) {
        // 获取方法名字
        String name = joinPoint.getSignature().getName();
        System.out.println(name+"方法的参数是:"+ Arrays.toString(joinPoint.getArgs()));
    }

    /**
     * 方法return之后执行
     * @param joinPoint 连接点,获取连接的方法的参数等信息
     * @param result 方法的返回值
     */
    @AfterReturning(value = "execution(public int com.demo.aop.CalImpl.*(..))",returning = "result")
    public void afterReturning(JoinPoint joinPoint,Object result){
        // 获取方法名字
        String name = joinPoint.getSignature().getName();
        System.out.println(name+"返回的结果为:"+result);
    }
}

3、实现类添加@Component注解
在这里插入图片描述

4、配置自动扫包,开启自动生成动态代理

bean.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
    <!--开启自动扫描包-->
    <context:component-scan base-package="com.demo.aop"></context:component-scan>

    <!--自动生成代理-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

5、测试
在这里插入图片描述

当日志信息需要改变时,我们只需要改变切面类中的打印信息即可,实现了核心代码和非业务代码的解耦合。

AOP的执行原理

容器中的计算器类通过切面对象自动生成代理对象,对代理对象进行操作。

一个代理对象只能对应一个目标类

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值