SpringAOP详解+使用aop完成添加日志

目录

1.什么是aop

2.为什么使用aop

3. AOP体系结构

 4.使用aop完成添加日志

 (1)导入pom依赖

(2)配置spring.xml文件

(3)准备一个测试接口

(4)测试接口的实现类

(5)创建切面类 添加的日志

(6)测试

5.aop通知类型

6.切点使用系统注解模式

7.切点使用自定义注解模式


1.什么是aop

AOP(Aspect Oriented Programming)面向切面思想,是Spring的三大 核心思想之一(AOP-面向切面、IOC-控制反转、DI-依赖注入)。

AOP,一般称为面向切面,作为面向对象OOP的一种补充,用于将那 些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取并 封装为一个可重用的模块,这个模块被命名为“切面”(Aspect),减少 系统中的重复代码,降低了模块间的耦合度,提高系统的可维护性。 可用于权限认证日志事务处理

2.为什么使用aop

Java是一个面向对象(OOP)的编程语言,但它有个弊端就是当需要为多 个不具有继承关系的对象引入一个公共行为时,例如日志记录、权限 校验、事务管理、统计等功能,只能在每个对象里都引用公共行为, 这样做不便于维护,而且有大量重复代码,AOP的出现弥补了OOP的 这点不足。

3. AOP体系结构

AOP要做的三件事在哪里切入,也就是权限校验等非业务操作在哪些业务 代码中执行;什么时候切入,是业务代码执行前还是执行后;切入后做什 么事,比如做权限校验、日志记录等。

 

  • Pointcut切点,决定处理如权限校验、日志记录等在何处切入业务代 码中(即织入切面)。切点分为execution方式和annotation方式。前 者可以用路径表达式指定哪些类织入切面,后者可以指定被哪些注解修 饰的代码织入切面。
  • Advice:处理,包括处理时机和处理内容。处理内容就是要做什么事, 比如校验权限和记录日志。处理时机就是在什么时机执行处理内容,分 为前置处理(即业务代码执行前)、后置处理(业务代码执行后)等。 
  • Aspect切面,即Pointcut和Advice。
  • Joint point连接点,是程序执行的一个点。例如,一个方法的执行或 者一个异常的处理。在 Spring AOP 中,一个连接点总是代表一个方法 执行。 
  • Weaving:织入,就是通过动态代理,在目标对象方法中执行处理内容 的过程。

 4.使用aop完成添加日志

 (1)导入pom依赖

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.2.15.RELEASE</version>
    </dependency>
    <!--切面依赖-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>5.2.15.RELEASE</version>
    </dependency>
</dependencies>

(2)配置spring.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:comtext="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">
    <!--包扫描-->
    <comtext:component-scan base-package="com.aaaa.demo02"/>
    <!--开启切面注解驱动 : 让spring可以识别切面的注解-->
    <aop:aspectj-autoproxy/>
</beans>

(3)准备一个测试接口


public interface MatheService {

    public int fun();
    //加法运算
    public void add(double a , double  b);
    //减法运算
    public void sub(double a , double  b);
    //乘法运算
    public void mul(double a , double  b);
    //除法运算
    public void div(double a , double  b);
}

(4)测试接口的实现类

@Service
public class MatheServiceImpl implements MatheService {
    //TODO 需求:执行业务代码前后添加日志
    //带返回值的方法
    public int fun(){
        System.out.println("fun方法的业务代码");
    return 100;
    }
    
    //加
    @Override
    public void add(double a, double b) {
       
        double result = a + b;
        System.out.println("计算的结果:" + result);
    }
    //减
    @Override
    public void sub(double a, double b) {
        double result = a-b ;
        System.out.println("计算的结果:"+result);
    }
    //乘
    @Override
    public void mul(double a, double b) {
        double result = a*b ;
        System.out.println("计算的结果:"+result);
    }
    //除
    @Override
    public void div(double a, double b) {
        double result = a/b ;
        System.out.println("计算的结果:"+result);
    }
}

(5)创建切面类 添加的日志

@Component //表示该类有spring容器创建
@Aspect   //表示该类为切面类
public class LogAspectj {
    /**
     *
     *  execution:表示哪些方法
     *  TODO 通配符:
     *           第一个*:表示访问任意修饰符和返回类型
     *           第二个*:表示该类下的任意类
     *           第三个*:表示任意方法
     *           .. : 表示任意参数类型和个数
     */
    //@Pointcut:切点
    @Pointcut("execution(* com.aaaa.demo02.*.*(..))")
    private void pointcut(){}
    @Before("pointcut()")//前置处理
    public void before(){
        System.out.println("前置日志~~~~~~");
    }
}

(6)测试

public class Test02 {
    public static void main(String[] args) {

        //读取spring配置文件
        ApplicationContext app = new ClassPathXmlApplicationContext("spring02.xml");
        //从spring容器获取指定的bean对象
        MatheService matheServiceImpl = (MatheService) app.getBean("matheServiceImpl");
        matheServiceImpl.div(10,10);
    }
}

5.aop通知类型

切面类中加入连接点(可以获取方法名称和参数)

 切面类中加入(后置通知 / 后置返回通知 / 异常通知)


//后置通知 :不管有没有异常都会执行
@After("pointcut()")
public void afterMethod(JoinPoint joinPoint){  //joinPoint:连接点
    Signature signature = joinPoint.getSignature(); //获取被切入的方法对象
    String name = signature.getName();  //获取方法名称
    System.out.println("后置日志~~~~~~ 方法名称:"+name);
}


//后置返回通知: 可以获取方法的返回值
@AfterReturning(value = ("pointcut()") , returning = "r")
public void afterReturningMethod(Object r){
    System.out.println("后置返回通知~~~~~返回值是:"+r);
}

//异常通知:发生异常执行
@AfterThrowing(value = ("pointcut()") , throwing = "e")
public void ex(Exception e){
    System.out.println("发生异常");
}

6.切点使用系统注解模式

配置pom/web/spring

 Controller层


@RestController  //表示该类为控制层并且该类中所有的方法返回的数据都是json数据
public class HelloController {
    @GetMapping("/hello")  //GetMapping:只处理get请求方式
    public String hello(){
        return "返回结果hello";
    }
    @PostMapping("/index")
    public String index(){
        return "返回index数据";
    }
}

日志

@Component
@Aspect
public class MyAspect {
    //定义切点
    @Pointcut("@annotation(org.springframework.web.bind.annotation.GetMapping)")
    private void my(){}
    //前置
    @Before("my()")
    public void aa(){
        System.out.println("前置++++++");
    }
}

7.切点使用自定义注解模式

定义自定义注解

@Target({ElementType.METHOD})   //表示该注解只能使用在方法上
@Retention(RetentionPolicy.RUNTIME)  //表示该注解在什么时候有效【Source源码时有效  CLASS字节码时有效  RUNTIME运行时有效】
@Documented
public @interface MyAnnotation {
    int value() default 0;
}

定义切点

@Component
@Aspect
public class MyAspect {
    //定义切点
    @Pointcut("@annotation(com.aaaa.demo03.MyAnnotation)")
    private void my(){}
    //前置
    @Before("my()")
    public void aa(){
        System.out.println("前置++qianqina++++");
    }
}

使用(使用自定义注解才会执行前置日志内容)

@MyAnnotation
@GetMapping("/show")
public void show(){
    System.out.println("自定义注解+++show+++");
}

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring AOP(面向切面编程)是Spring框架中的一个模块,用于提供横切关注点(Cross-Cutting Concerns)的支持。横切关注点是与应用程序的核心业务逻辑无关的功能,例如日志记录、性能统计、事务管理等。 在Spring AOP中,通过定义切面(Aspect)来捕获横切关注点,并将其应用到目标对象的方法中。切面由切点(Pointcut)和通知(Advice)组成。切点定义了在何处应用通知,通知则定义了在切点处执行的操作。 Spring AOP支持以下几种类型的通知: 1. 前置通知(Before Advice):在目标方法执行之前执行的通知。 2. 后置通知(After Advice):在目标方法执行之后执行的通知,不管方法是否抛出异常。 3. 返回通知(After Returning Advice):在目标方法成功执行并返回结果后执行的通知。 4. 异常通知(After Throwing Advice):在目标方法抛出异常后执行的通知。 5. 环绕通知(Around Advice):围绕目标方法执行的通知,可以在方法调用前后执行自定义操作。 除了通知,Spring AOP还支持引入(Introduction)和切点表达式(Pointcut Expression)等功能。引入允许为目标对象添加新的接口和实现,而切点表达式则允许开发人员定义切点的匹配规则。 要在Spring应用程序中使用AOP,需要进行以下步骤: 1. 引入Spring AOP的依赖。 2. 配置AOP代理。 3. 定义切面和通知。 4. 配置切点和通知之间的关系。 总之,Spring AOP提供了一种便捷的方式来处理横切关注点,使得开发人员可以将关注点与核心业务逻辑分离,提高代码的可维护性和可重用性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值