SpringBoot AOP(内含源代码)

源代码下载链接:


目录

  • SpringBoot AOP(内含源代码)
  • `源代码下载链接:`[]()
  • 写法一: @Before("execution(* com.bjpowernode.springboot07.javabean.Man.eat(..))")
  • 一、AOP开发
  • 1.1 概述
  • 1.2使用方法
  • 1.3创建项目并添加maven依赖
  • 1.4 创建Javabean测试类
  • 1.5 创建切面
  • 1.6 测试类
  • 1.7 测试结果
  • 1.8 结论
  • 1.9 代理方式的切换
  • 1.9.1 设计一个接口ManInterface
  • 1.9.2 javaBean目标类Man实现ManInterface接口
  • 1.9.3 修改application.yml文件的切换方式代理方式
  • 1.9.4 测试类
  • 1.9.5 测试结果
  • 写法二:
  • public static final String POINT_CUT = "execution(* com.bjpowernode.springboot03aop.domain.Man.*(..))";
  • @Before(value=POINT_CUT)
  • 二、AOP开发
  • 2.1 pom.xml
  • 2.2 javabean
  • 2.3 切面类(不一样的地方)
  • 2.4 测试类
  • 2.5 测试结果
  • 写法三:
  • 三、AOP开发
  • 3.1 pom.xml
  • 3.2 javabean
  • 3.3 切面类(不一样的地方)
  • 3.4 测试类
  • 3.5 测试结果


写法一: @Before(“execution(* com.bjpowernode.springboot07.javabean.Man.eat(…))”)

一、AOP开发

1.1 概述

aop是spring的两大功能模块之一,功能非常强大,为解耦提供了非常优秀的解决方案。SpringBoot集成aop是非常方便的,下面使用aop来拦截业务组件的方法

Aop的作用:在不修改源代码的情况下,对类里面的方法进行增强(前置,后置,环绕,异常)

Aop的关键点:
切入点: 被增强的方法
通知/增强: 就是具体增强的代码

1.2使用方法

使用springboot操作aop 与 直接使用spring的注解方式操作aop方式是一致的

1.3创建项目并添加maven依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

1.4 创建Javabean测试类

javabean

Man.java

package com.bjpowernode.springboot07.javabean;

import lombok.Data;
import org.springframework.stereotype.Component;

@Data
@Component
public class Man {
    public void eat(String foodName){
        System.out.println(foodName+"真好吃");
    }

}

1.5 创建切面

package com.bjpowernode.springboot07.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class ManAspect {

    @Before("execution(* com.bjpowernode.springboot07.javabean.Man.eat(..))")
    public void beforeAdvice(){
        System.out.println("ManAspect.beforeAdvice");
    }

    @After("execution(* com.bjpowernode.springboot07.javabean.Man.eat(..))")
    public void afterAdvice(){
        System.out.println("ManAspect.afterAdvice");
    }

    @Around("execution(* com.bjpowernode.springboot07.javabean.Man.eat(..))")
    public void aroundAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("ManAspect.aroundAdvice--start");
        proceedingJoinPoint.proceed();
        System.out.println("ManAspect.aroundAdvice--end");
    }
}

1.6 测试类

package com.bjpowernode.springboot07;

import com.bjpowernode.springboot07.javabean.Man;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class Springboot07ApplicationTests {
    @Autowired
    private Man man;

    @Test
    public void testAop(){
        System.out.println(man.getClass().getName());
        man.eat("油条");
    }

}

1.7 测试结果

spring boot 通过 Aop 统一返回结果 springboot aop before_开发语言

1.8 结论

springboot aop 默认的动态代理方式为cglib
SpringBoot 2.x开始,AOP为了解决使用JDK动态代理可能导致的类型转换异常,而使用CGLIB。

1.9 代理方式的切换

使用JDK动态代理的方式

1.9.1 设计一个接口ManInterface

package com.bjpowernode.springboot07.javabean;

public interface ManInterface {
    void eat(String foodName);
}

1.9.2 javaBean目标类Man实现ManInterface接口

spring boot 通过 Aop 统一返回结果 springboot aop before_IDEA_02

package com.bjpowernode.springboot07.javabean;

import lombok.Data;
import org.springframework.stereotype.Component;

@Data
@Component
public class Man implements ManInterface{
    public void eat(String foodName){
        System.out.println(foodName+"真好吃");
    }

}

从springBoot2.x以后,切换代理方式需要在配置文件中配置,使用注解切换的方式失效了

spring boot 通过 Aop 统一返回结果 springboot aop before_开发语言_03

1.9.3 修改application.yml文件的切换方式代理方式

spring:
    aop:
        proxy-target-class: false # false表示使用JDK代理  true表示使用CGLIB代理,SpringBoot2.x以后默认使用CGLIB代理

1.9.4 测试类

需要改为注入接口

package com.bjpowernode.springboot07;

import com.bjpowernode.springboot07.javabean.Man;
import com.bjpowernode.springboot07.javabean.ManInterface;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class Springboot07ApplicationTests {


    @Autowired
    private ManInterface man;


    @Test
    public void testAop(){
        System.out.println(man.getClass().getName());
        man.eat("油条");
    }
}

1.9.5 测试结果

spring boot 通过 Aop 统一返回结果 springboot aop before_IDEA_04

写法二:

public static final String POINT_CUT = “execution(* com.bjpowernode.springboot03aop.domain.Man.*(…))”;

@Before(value=POINT_CUT)

二、AOP开发

2.1 pom.xml

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

2.2 javabean

Man.java

package com.bjpowernode.springboot03aop.domain;

import org.springframework.stereotype.Component;

/*
*将此类加入IOC管理
* AOP作用的类一定要加入IOC容器中
*/
@Component
public class Man {

    /**
     * 吃饭的方法
     * @param foodName
     * @return
     */
    public String eat(String foodName){
        System.out.println("吃"+foodName);
        int i=1/0;
        return foodName+"很好吃";
    }

}

2.3 切面类(不一样的地方)

package com.bjpowernode.springboot03aop.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/*
*切面类加入IOC容器管理
* 添加切面的标识
*/
@Aspect
@Component
public class ManAspect {

    /*
    *切入点
    */
    public static final String POINT_CUT = "execution(* com.bjpowernode.springboot03aop.domain.Man.*(..))";

    /*
    * 前置通知
    */
    @Before(value=POINT_CUT)
    public void before(){
        System.out.println("吃饭前洗手");
    }

    /*
    * 后置通知
    */
    @After(POINT_CUT)
    public void after(){
        System.out.println("饭后甜点");
    }

    /**
     * 环绕通知
     * @param proceedingJoinPoint
     * @return
     */
    @Around(value = POINT_CUT)
    public Object around(ProceedingJoinPoint proceedingJoinPoint){
        Object result = null;
        try {
            System.out.println("执行目标方法之前");
            //执行目标方法
            result = proceedingJoinPoint.proceed();
            System.out.println("执行目标方法之后");
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return result;
    }

    /**
     * 异常通知
     * @param ex
     */
    @AfterThrowing(value = POINT_CUT,throwing = "ex")
    public void afterThrowing(Throwable ex){
        System.out.println("异常了"+ex.getMessage());
    }

}

2.4 测试类

package com.bjpowernode.springboot03aop;

import com.bjpowernode.springboot03aop.domain.Man;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class Springboot03AopApplicationTests {

    @Autowired
    private Man man;

    @Test
    void contextLoads() {
        System.out.println(man.getClass().getName());
        man.eat("面条");
    }

}

2.5 测试结果

spring boot 通过 Aop 统一返回结果 springboot aop before_开发语言_05

写法三:

三、AOP开发

3.1 pom.xml

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

3.2 javabean

Man.java

package com.bjpowernode.springboot03aop.domain;

import org.springframework.stereotype.Component;

/*
*将此类加入IOC管理
* AOP作用的类一定要加入IOC容器中
*/
@Component
public class Man {

    /**
     * 吃饭的方法
     * @param foodName
     * @return
     */
    public String eat(String foodName){
        System.out.println("吃"+foodName);
        int i=1/0;
        return foodName+"很好吃";
    }

}

3.3 切面类(不一样的地方)

package com.bjpowernode.springboot03aop2.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/*
*切面类加入IOC容器管理
* 添加切面的标识
*/
@Aspect
@Component
public class ManAspect {

    @Pointcut("execution(* com.bjpowernode.springboot03aop2.domain.Man.*(..))")
    public void pointCutMethod(){

    }

    /*
    * 前置通知
    */
    @Before("pointCutMethod()")
    public void before(){
        System.out.println("吃饭前洗手");
    }

    /*
    * 后置通知
    */
    @After("pointCutMethod()")
    public void after(){
        System.out.println("饭后甜点");
    }

    /**
     * 环绕通知
     * @param proceedingJoinPoint
     * @return
     */
    @Around("pointCutMethod()")
    public Object around(ProceedingJoinPoint proceedingJoinPoint){
        Object result = null;
        try {
            System.out.println("执行目标方法之前");
            //执行目标方法
            result = proceedingJoinPoint.proceed();
            System.out.println("执行目标方法之后");
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return result;
    }

    /**
     * 异常通知
     * @param ex
     */
    @AfterThrowing(value = "pointCutMethod()",throwing = "ex")
    public void afterThrowing(Throwable ex){
        System.out.println("异常了"+ex.getMessage());
    }

}

3.4 测试类

package com.bjpowernode.springboot03aop;

import com.bjpowernode.springboot03aop.domain.Man;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class Springboot03AopApplicationTests {

    @Autowired
    private Man man;

    @Test
    void contextLoads() {
        System.out.println(man.getClass().getName());
        man.eat("面条");
    }

}

3.5 测试结果

spring boot 通过 Aop 统一返回结果 springboot aop before_开发语言_05