SpringBoot AOP(内含源代码)

导读:本篇文章讲解 SpringBoot AOP(内含源代码),希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

SpringBoot AOP(内含源代码)

源代码下载链接:https://download.csdn.net/download/weixin_46411355/87399904

写法一: @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 测试结果

在这里插入图片描述

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接口

在这里插入图片描述

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以后,切换代理方式需要在配置文件中配置,使用注解切换的方式失效了
在这里插入图片描述

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 测试结果

在这里插入图片描述

写法二:

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 测试结果

在这里插入图片描述

写法三:

三、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 测试结果

在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/85521.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!