Spring之AOP系列--使用/实例_IT利刃出鞘的博客-程序员信息网

技术标签: spring  spring boot  java  Java面试真题  

原文网址:Spring之AOP系列--使用/实例_IT利刃出鞘的博客-程序员信息网

简介

        本文介绍Spring(SpringBoot)的AOP的用法,以及其顺序的控制。

AOP的执行流程图

正常执行时的流程

代码抛异常时的流程

创建工程

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo_springaop-simple</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo_springaop-simple</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

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

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <!--            <exclusions>-->
            <!--                <exclusion>-->
            <!--                    <groupId>org.junit.vintage</groupId>-->
            <!--                    <artifactId>junit-vintage-engine</artifactId>-->
            <!--                </exclusion>-->
            <!--            </exclusions>-->
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.20</version>
            <scope>provided</scope>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

公共代码

启动类

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoSpringaopSimpleApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoSpringaopSimpleApplication.class, args);
    }
}

Entity

package com.example.demo.entity;

import lombok.Data;

@Data
public class User {
    private Integer id;
    private String userName;
    private String note;
}

Service

package com.example.demo.service;

import com.example.demo.entity.User;

public interface UserService {
    public void printUser(User user);
}
package com.example.demo.service.impl;

import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {
    @Override
    public void printUser(User user) {
        if (user == null) {
            throw new RuntimeException("检查用户参数是否为空");
        }
        System.out.print("id = " + user.getId());
        System.out.print("\t userName = " + user.getUserName());
        System.out.println("\t note = " + user.getNote());
    }
}

Controller

package com.example.demo.controller;

import com.example.demo.annotation.OperationLog;
import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@RequestMapping("/user")
@Controller
public class UserController {
    @Autowired
    private UserService userService;

    @RequestMapping("/print")
    @ResponseBody
    public User testPrint(User user) {
        userService.printUser(user);
        return user;
    }

    @RequestMapping("/add")
    @ResponseBody
    @OperationLog(type = "添加", desc = "添加数据")
    public User testAdd(User user) {
        return user;
    }

    @RequestMapping("/update")
    @ResponseBody
    @OperationLog(type = "更新", desc = "更新数据")
    public User testUpdate(User user) {
        userService.printUser(user);
        return user;
    }
}

AOP代码

代码

package com.example.demo.aspect;

import com.example.demo.annotation.OperationLog;
import com.example.demo.common.util.JsonUtil;
import com.example.demo.entity.User;
import com.sun.org.apache.regexp.internal.RE;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Component
// @Order(1)
public class SimpleAspect {
    @Pointcut("execution(* com.example.demo.service.impl.UserServiceImpl.printUser(..))")
    // 多个切点时可指定优先级
    // @Order(1)
    public void pointCut() {

    }

    @Before("pointCut()")
    public void before() {
        System.out.println("############################ SimpleAspect.before ############################");
    }

    @Around("pointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("############################ SimpleAspect.around ############################");
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        System.out.println("joinPoint.getTarget().toString()  : " + joinPoint.getTarget().toString());
        System.out.println("methodSignature.getName()         : " + methodSignature.getName());
        System.out.println("method.getName()                  : " + method.getName());
        System.out.println("method.getReturnType().getName()  : " + method.getReturnType().getName());

        Object[] objects = joinPoint.getArgs();
        System.out.println(JsonUtil.toJson(objects));

        System.out.println("------------ SimpleAspect.around: proceed之前 ------------");
        Object object = joinPoint.proceed();
        System.out.println("------------ SimpleAspect.around: proceed返回值 ------------");
        System.out.println(JsonUtil.toJson(object));
        System.out.println("------------ SimpleAspect.around: proceed之后 ------------");

        return object;
    }

    @AfterReturning(value = "pointCut()", returning = "returnValue")
    public void afterReturning(JoinPoint joinPoint, Object returnValue) {
        System.out.println("############################ SimpleAspect.afterReturning ############################");
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        System.out.println("------------ SimpleAspect.afterReturning: 方法名字 ------------");
        System.out.println(method.getName());
        System.out.println("------------ SimpleAspect.afterReturning: 返回值 ------------");
        System.out.println(JsonUtil.toJson(returnValue));
    }

    @AfterThrowing(value = "pointCut()", throwing = "throwingValue")
    public void afterThrowing(JoinPoint joinPoint, Throwable throwingValue) {
        System.out.println("############################ SimpleAspect.afterThrowing ############################");
        // MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        // Method method = methodSignature.getMethod();
        System.out.println("------------ SimpleAspect.afterThrowing: 异常信息 ------------");
        System.out.println(throwingValue.getMessage());
    }

    /**
     * 无法获得返回值,只能获得参数
     */
    @After("pointCut()")
    public void after() {
        System.out.println("############################ SimpleAspect.after ############################");
    }
}

测试

后端结果

############################ SimpleAspect.around ############################
joinPoint.getTarget().toString()  : [email protected]
methodSignature.getName()         : printUser
method.getName()                  : printUser
method.getReturnType().getName()  : void
[{"id":321,"userName":"Tony","note":"abc"}]
------------ SimpleAspect.around: proceed之前 ------------
############################ SimpleAspect.before ############################
id = 321	 userName = Tony	 note = abc
############################ SimpleAspect.afterReturning ############################
------------ SimpleAspect.afterReturning: 方法名字 ------------
printUser
------------ SimpleAspect.afterReturning: 返回值 ------------
null
############################ SimpleAspect.after ############################
------------ SimpleAspect.around: proceed返回值 ------------
null
------------ SimpleAspect.around: proceed之后 ------------

可以看到,返回值为null,因为printUser方法没有返回值。 

其他网址

《深入浅出Spring Boot 2.x》=> 4.3 AOP开发详解

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/feiying0canglang/article/details/120711539

智能推荐

matplotlib xticks用法_pyplot xticks_hhggggghhh的博客-程序员信息网

这个坐标轴变名用法,我真服气了,我在网上看大家写的教程,看的头晕,也没看懂他们写xtick到底怎么用的,最后找到官方教程,看了一个例子,overxticks到底有什么用,其实就是想把坐标轴变成自己想要的样子import matplotlib.pyplot as pltx = [1, 2, 3, 4]y = [1, 4, 9, 6]labels = ['Frogs', 'Hogs', ...

css居中和布局_东方逸岚的博客-程序员信息网

<div id="breadcrumb" class="grid-12 margin-20"><div class="breadcrumb-wrapper"><!-- Breadcrumb NavXT 4.4.0 -->伯乐在线 > WEB前端 - 伯乐在线 > 所有文章 > CSS > CSS 布局十八般武艺都在这里了 CSS 布局十八般武艺都在这里

SGAN阅读笔记_sgan的损失函数_storm岚的博客-程序员信息网

SGAN阅读笔记引言:利用GAN生成适合进行隐写的图片,SGAN由生成器G,判别器D,S。G是生成用于隐写的图片,其输入为随机噪声。判别器D是用来判别图像真假,其输入为真是的图片和生成的图片。判别器S用于判断图片是否含有隐藏数据。通过对抗训练,可以使G产生逼真且适合用于隐写的图片。原理:根据Good fellow提出的GAN,对其进行修改。其损失函数为:SGAN的模型为:采用随机小批次梯...

【JavaWeb】Cookie&Session学习笔记(黑马)_weiambt的博客-程序员信息网

今日内容1. 会话技术 1. Cookie 2. Session2. JSP:入门学习会话技术1. 会话:一次会话中包含多次请求和响应。 * 一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止2. 功能:在一次会话的范围内的多次请求间,共享数据3. 方式: 1. 客户端会话技术:Cookie 2. 服务器端会话技术:SessionCookie:1. 概念:客户端会话技术,将数据保存到客户端2. 快速入门: * 使用步骤: 1. 创建Cookie对

VSCode,选择在终端执行,切换默认终端(cmd、powershell)_vs code new terminal powershell默认执行_wxyoug的博客-程序员信息网

若默认终端是powershell,需要添加cmd:(1)ctrl+shift+p打开命令面d板,输入select ,选中Terminal:Select Default Shell(2) 点击cmd.exe,再重新打开终端执行,即可添加成功。

微软Kinect完全拆解_圣徒子的博客-程序员信息网

<br />微软Kinect体感套装昨天在国外刚刚发售,就有不少网友发出这样的感叹。的确,从国外网站对Kinect的拆解分析来看,这个漂亮的小家伙确实长得很像《霹雳5号》中那台可爱的Johnny 5机器人。Kinect拥有两个摄像头,两个麦克风,足够让你满意的音频单元,以及强劲的处理能力。除此以外,它还首次在游戏机外设上引入了加速度计,告诉设备我们正在指向哪里。这个小家伙的内部结构是如此错综复杂,以至于需要一个风扇进行主动散热,至少在目前,Kinect是最复杂游戏外设排行榜上的NO.1。<br />让我们来

随便推点

实战项目成果展示_Kyrie_tim的博客-程序员信息网

#房价影响因素挖掘##电商打折套路解析##城市餐饮店铺选址分析#

LCD1602液晶显示_lcd1602显示程序设计_比特冬哥的博客-程序员信息网

LCD1602液晶显示器是广泛使用的一种字符型液晶显示模块。它是由字符型液晶显示屏(LCD)、控制驱动主电路HD44780及其扩展驱动电路。

重定义fputc函数到串口printf输出(代码 + 应用实例)_努力的小肥丸的博客-程序员信息网

文章目录前言一、重定义fputc函数写法1(我目前使用的)写法2(网上常见的)写法3(网上常见的)一起交流一下鸭~二、勾选Use MicroLib三、main函数中应用printf输出四、注意事项(问题现象:程序卡在fputc函数)五、小结前言芯片型号:STM32F103VCT6串口:USART1目的:重定义fputc函数到串口输出,实现printf一、重定义fputc函数写法1(我目前使用的)int fputc(int ch, FILE *f){ /* 发送一个字

UNIX系统V(System V)_unix system v_中杯的拿铁的博客-程序员信息网

目录概述信息摘要总览介绍AT&amp;T的支持与BSD的对抗竞争发布版SVR1SVR2SVR3SVR4SVR4.2 / UnixWareSVR5 / UnixWare 7SVR6 (取消)市场地位20世纪90年代在x86平台上的可用性蒙特利项目系统V和Unix市场占有情况OpenSolaris和illumos发行版系统V的兼容性概述Unix系统V(英文读作“System Five”,即“系统五”)是Unix操作系统.

欧拉计划[C++]_m0_54285007的博客-程序员信息网

02#include&lt;iostream&gt;using namespace std;int main(){ int first = 1, second = 2, temp = 0, sum = 2; while (temp &lt; 4000000) { temp = first + second; if (temp % 2 == 0 &amp;&amp;temp &lt; 4000000) { sum += temp; } first = second;

NOI题库答案 (1.7 字符串基础)(1-20)_Dunyb的博客-程序员信息网

 01:统计数字字符个数描述输入一行字符,统计出其中数字字符的个数。输入一行字符串,总长度不超过255。输出输出为1行,输出字符串里面数字字符的个数。样例输入Peking University is set up at 1898.样例输出4#include&amp;lt;bits/stdc++.h&amp;gt;using namespace std;in...

推荐文章

热门文章

相关标签