SpringBoot之自定义简单的注解和AOP

news/2025/2/25 9:10:35

1.引入依赖

<!-- AOP依赖-->
<dependency>
	<groupId>org.aspectj</groupId>
	<artifactId>aspectjweaver</artifactId>
	<version>1.9.8</version>
</dependency>

2.自定义一个注解

java">package com.example.springbootdemo3.annotation;

import java.lang.annotation.*;

@Target({ElementType.METHOD}) // 指定该注解可以加在方法上
@Retention(RetentionPolicy.RUNTIME) // 指定该注解在运行时保留,可以通过反射获取
@Documented // 表明该注解被包含在javadoc中
public @interface MyLog {

    /**
     * 名称
     */
    String name() default "";
}

3.自定义AOP

java">package com.example.springbootdemo3.aop;

import com.example.springbootdemo3.annotation.MyLog;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

/**
 * description
 * 自定义ControllerAOP
 *
 * @author PC 2025/02/24 20:37
 */
@Component
@Aspect
public class MyControllerAop {
    // 定义使用MyLog注解的方法为切入点
    @Pointcut("@annotation(com.example.springbootdemo3.annotation.MyLog)")
    private void pointCut() {
    }

    @Around("pointCut()") // 注解表示该方法是一个环绕通知(around advice),它会在指定的切入点(pointcut)执行前后进行增强处理。
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        // 获取倍增强调的类和方法信息
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        // 获取被增强的方法对象
        Method method = methodSignature.getMethod();
        // 获取被增强的方法上的注解
        if (method != null) {
            MyLog myLog = method.getAnnotation(MyLog.class);
            System.out.println("MyLog name:" + myLog.name());
        }
        // 方法名
        String name = method.getName();
        System.out.println("方法名:" + name);

        // 获取Request对象
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = servletRequestAttributes.getRequest();
        // 访问url
        String url = request.getRequestURL().toString();
        System.out.println("访问url:" + url);
        // 请求方式
        String method1 = request.getMethod();
        System.out.println("请求方式:" + method1);
        // 请求参数
        String queryString = request.getQueryString();
        System.out.println("请求参数:" + queryString);
        // 请求IP
        System.out.println("请求IP:" + getClientIpAddress(request));
        Object proceed = joinPoint.proceed();
        System.out.println("返回值:" + proceed);
        return proceed;
    }

    /**
     * 方法:获取真实IP地址
     * 从常见的IP所在的请头中来获取
     *
     * @param request
     * @return
     */
    private String getClientIpAddress(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
}

3.写个测试Controller试一下

java">package com.example.springbootdemo3.config;

import com.example.springbootdemo3.annotation.MyLog;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

/**
 * description
 *
 * @author PC 2025/02/24 21:29
 */
@RestController
@RequestMapping("/aop-test")
public class AopTestController {
    @PostMapping("/test")
    @MyLog(name = "aop测试")
    public String aopTest(@RequestBody Map map) {
        System.out.println(map);
        return "success";
    }
}

4.结束

在这里插入图片描述


http://www.niftyadmin.cn/n/5865302.html

相关文章

鸿蒙ArkTS页面如何与H5页面交互?

鸿蒙页面如何与H5页面交互&#xff1f; 先看效果前言通信功能介绍Web组件使用问题 Harmony OS NEXT版本&#xff08;接口及解决方案兼容API12版本或以上版本) 先看效果 功能介绍 点击Click Me按钮可以接收展示鸿蒙传递给html的内容点击霓虹灯按钮可以同步更新底部鸿蒙页面的按…

Flutter系列教程之(2)——Dart语言快速入门

目录 1.变量与类型 1.1 num类型 1.2 String类型 1.3 Object与Dynamic 1.4 类型判断/转换 1.5 变量和常量 2.方法/函数 3.类、接口、抽象类 3.1 类 3.2 接口 4.集合 4.1 List 4.2 Set 4.3 Map 5.总结 Dart语言的语法和Kotlin、Java有类似之处&#xff0c;这里就通…

ADCS-ESC1漏洞环境构造与利用

原理 ESC1是ADCS中的一个漏洞&#xff0c;利用该漏洞可实现权限提升攻击。在 ESC1 漏洞利用中&#xff0c;攻击者通过一系列操作获取包含域管身份信息的证书后&#xff0c;利用 Rubeus.exe 工具&#xff0c;使用该证书获取 TGT 票据。一旦成功获取 TGT 票据&#xff0c;攻击者…

ubuntu windows双系统踩坑

我有个台式机&#xff0c;先安装的ubuntu&#xff0c;本来想专门用来做开发&#xff0c;后面儿子长大了&#xff0c;给他看了一下星际争霸、魔兽争霸&#xff0c;立马就迷上了。还有一台windows的笔记本&#xff0c;想着可以和他联局域网一起玩&#xff0c;在ubuntu上用wine跑魔…

react使用react-quill 富文本插件、加入handlers富文本不显示解决办法

可以调整图片大小 quill-image-resize-module-react 加入插件quill-image-resize-module-reactQuill.register("modules/imageResize", ImageResize); // 注册图片缩放富文本配置中加入如下const quildConfig {toolbar: {container: [["bold", "ital…

qt:多元素类,容器类,布局类

1.列表 List Widget 属性特点currentRow当前被选中的是第几行count一共有多少行sortingEnabled是否允许排序isWrapping是否允许换行itemAlignment元素的对齐方式selectRectVisible被选中的元素矩形是否可见spacing元素之间的间隔 方法特点addItem(const QString& label)…

【现代深度学习技术】卷积神经网络 | 图像卷积

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈PyTorch深度学习 ⌋ ⌋ ⌋ 深度学习 (DL, Deep Learning) 特指基于深层神经网络模型和方法的机器学习。它是在统计机器学习、人工神经网络等算法模型基础上&#xff0c;结合当代大数据和大算力的发展而发展出来的。深度学习最重…

vue框架后遗症∶被遗忘的dom操作

用多了vue、react等前端框架&#xff0c;不得不说用数据驱动视图来开发真的很香&#xff0c;但是也免不了会有不用这些框架的项目&#xff0c;dom操作还是很有必要的&#xff0c;一开始学习网页设计的时候就教过&#xff0c;后面一直开发项目基本上用框架。虽然有些想不起来了&…