首页 > 编程语言 >SpringBoot中使用Aspect实现切面

SpringBoot中使用Aspect实现切面

时间:2023-12-19 16:57:06浏览次数:40  
标签:SpringBoot aspect 切面 Aspect org import com annotation String

相关概念

  1. 切面(Aspect):
    首先要理解‘切’字,需要把对象想象成一个立方体,传统的面向对象变成思维,类定义完成之后(封装)。每次实例化一个对象,对类定义中的成员变量赋值,就相当于对这个立方体进行了一个定义,定义完成之后,就等着被使用,等着被回收。

面向切面编程则是指,对于一个我们已经封装好的类,我们可以在编译期间或在运行期间,对其进行切割,把立方体切开,在原有的方法里面添加(织入)一些新的代码,对原有的方法代码进行一次增强处理。而那些增强部分的代码,就被称之为切面,如下面代码实例中的通用日志处理代码,常见的还有事务处理、权限认证等等。

  1. 切入点(PointCut):
    要对哪些类中的哪些方法进行增强,进行切割,指的是被增强的方法。即要切哪些东西。

  2. 连接点(JoinPoint):
    知道了要切哪些方法后,剩下的就是什么时候切,在原方法的哪一个执行阶段加入增加代码,这个就是连接点。如方法调用前,方法调用后,发生异常时等等。

  3. 通知(Advice):
    通知被织入方法,改如何被增强。定义切面的具体实现。那么这里面就涉及到一个问题,空间(切哪里)和时间(什么时候切,在何时加入增加代码),空间我们已经知道了就是切入点中定义的方法,而什么时候切,则是连接点的概念。

  4. 目标对象(Target Object):
    被一个或多个切面所通知的对象,即为目标对象。

  5. AOP代理对象(AOP Proxy Object):
    AOP代理是AOP框架所生成的对象,该对象是目标对象的代理对象。代理对象能够在目标对象的基础上,在相应的连接点上调用通知。

  6. 织入(Weaving):
    将切面切入到目标方法之中,使目标方法得到增强的过程被称之为织入。

AOP 必须的依赖

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

日志实体类

package com.space.aspect.bo;
 
import lombok.Data;
 
/**
 * 系统日志bo
 */
@Data
public class SysLogBO {
 
    private String className;
 
    private String methodName;
 
    private String params;
 
    private Long exeuTime;
 
    private String remark;
 
    private String createDate;
}

日志service

package com.space.aspect.service;
 
import com.space.aspect.bo.SysLogBO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
 
@Slf4j
@Service
public class SysLogService {
 
    public boolean save(SysLogBO sysLogBO){
        // 这里就不做具体实现了
        log.info(sysLogBO.getParams());
        return true;
    }
 
}

定义日志注解

package com.space.aspect.anno;
 
import java.lang.annotation.*;
 
/**
 * 定义系统日志注解
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SysLog {
    String value() default "";
}

声明切面,完成日志记录

以上4点我们的准备工作已经完成。接下来就是重点了

package com.space.aspect.aspect;
 
import com.google.gson.Gson;
import com.space.aspect.anno.SysLog;
import com.space.aspect.bo.SysLogBO;
import com.space.aspect.service.SysLogService;
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.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
 
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 系统日志切面
 */
@Aspect  // 使用@Aspect注解声明一个切面
@Component
public class SysLogAspect {
 
    @Autowired
    private SysLogService sysLogService;
 
    /**
     * 这里我们使用注解的形式
     * 当然,我们也可以通过切点表达式直接指定需要拦截的package,需要拦截的class 以及 method
     * 切点表达式:   execution(...)
          *
     * execution(public * *(..)) 任意的公共方法
     * execution(* set*(..)) 以set开头的所有的方法
     * execution(* com.LoggerApply.*(..))com.LoggerApply这个类里的所有的方法
     * execution(* com.annotation.*.*(..))com.annotation包下的所有的类的所有的方法
     * execution(* com.annotation..*.*(..))com.annotation包及子包下所有的类的所有的方法
     * execution(* com.annotation..*.*(String,?,Long)) com.annotation包及子包下所有的类的有三个参数,第一个参数为String类型,第二个参数为任意类型,第三个参数为Long类型的方法
     * execution(@annotation(com.lingyejun.annotation.Lingyejun))
     */
    @Pointcut("@annotation(com.space.aspect.anno.SysLog)")
    public void logPointCut() {}
 
    /**
     * 环绕通知 @Around  , 当然也可以使用 @Before (前置通知)  @After (后置通知)
     * @param point
     * @return
     * @throws Throwable
     */
    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        long beginTime = System.currentTimeMillis();
        Object result = point.proceed();
        long time = System.currentTimeMillis() - beginTime;
        try {
            saveLog(point, time);
        } catch (Exception e) {
        }
        return result;
    }
 
    /**
     * 保存日志
     */
    private void saveLog(ProceedingJoinPoint joinPoint, long time) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        SysLogBO sysLogBO = new SysLogBO();
        sysLogBO.setExeuTime(time);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        sysLogBO.setCreateDate(dateFormat.format(new Date()));
        SysLog sysLog = method.getAnnotation(SysLog.class);
        if(sysLog != null){
            //注解上的描述
            sysLogBO.setRemark(sysLog.value());
        }
        //请求的 类名、方法名
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = signature.getName();
        sysLogBO.setClassName(className);
        sysLogBO.setMethodName(methodName);
        //请求的参数
        Object[] args = joinPoint.getArgs();
        try{
            List<String> list = new ArrayList<String>();
            for (Object o : args) {
                list.add(new Gson().toJson(o));
            }
            sysLogBO.setParams(list.toString());
        }catch (Exception e){ }
        sysLogService.save(sysLogBO);
    }
}

测试

package com.space.aspect.controller;
 
import com.space.aspect.anno.SysLog;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
 
@RestController
public class TestController {
 
    @SysLog("测试")
    @GetMapping("/test")
    public String test(@RequestParam("name") String name){
        return name;
    }
}

标签:SpringBoot,aspect,切面,Aspect,org,import,com,annotation,String
From: https://www.cnblogs.com/codeLearn/p/17914156.html

相关文章

  • 最近在使用SpringBoot整合MyBatis-Plus时出现的问题
    版本信息:IDEA2022、jdk17、maven3.8.6、SpringBoot3+MyBatis-Plus依赖版本信息:<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3</version&g......
  • springboot 记录使用log4j与logback发送日志到syslog服务器
    Linux服务器配置编辑/etc/rsyslog.conf文件。(我的在这里,根据自己系统查看)#取消注释这几行$ModLoadimudp$UDPServerRun514#ProvidesTCPsyslogreception$ModLoadimtcp$InputTCPServerRun514..........#末位追加:local2.info/var/log/login_info.log......
  • SpringBoot读取resources下的文件以及resources的资源路径
    1.这种可以但是在容器中获取不到(以下几种都可以只要不在容器)。InputStreaminputStream=this.getClass().getResourceAsStream("/static/imgs/aha.png");Propertiespps=newProperties();Filefile=ResourceUtils.getFile("classpath:defult.properties");pps.loa......
  • SpringBoot启动热部署
    1.在pom.xml中添加依赖<!--devtools热部署--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</opt......
  • 【转载】Springboot2.x 使用 Redis
    参考https://blog.csdn.net/weixin_43749805/article/details/131399516https://juejin.cn/post/7076244567569203208https://blog.csdn.net/oJingZhiYuan12/article/details/126386904注意classjava.lang.Integercannotbecasttoclasscom.xiaqiuchu.demo.entity.S......
  • springboot015粮食仓库管理系统(毕业设计,附数据库和源码)
    一.4开发的技术介绍一.4.1Springboot介绍一.4.2Java语言一.4.3MySQL数据库一.5论文的结构二需求分析二.1需求设计二.2可行性分析二.2.1技术可行性二.2.2经济可行性二.2.3操作可行性二.3功能需求分析表2-1粮食仓库管理系统功能结构图三系统设计三.1数据库概念结构......
  • springboot012响应式企业员工绩效考评系统(vue,毕业设计,附源码和数据库)
    2 关键技术2.1SpringBoot框架2.2 Maven环境2.3Mysql数据库2.4Vue.js框架2.5小结4 系统分析与设计4.1系统架构在对一个系统的开发中,必须全面的考虑用户对学校系统的需求,这个步骤需要开发出系统的功能的用途,每个图应代表系统的一个功能模块。系统架构图:4.2系统功能设......
  • springboot045新闻推荐系统-计算机毕业设计源码+LW文档
    摘要随着信息互联网购物的飞速发展,国内放开了自媒体的政策,一般企业都开始开发属于自己内容分发平台的网站。本文介绍了新闻推荐系统的开发全过程。通过分析企业对于新闻推荐系统的需求,创建了一个计算机管理新闻推荐系统的方案。文章介绍了新闻推荐系统的系统分析部分,包括可行性分......
  • springboot011流浪动物救助网站(vue)
    4需求分析4.1需求调研在教学网站中,能够在网站上运行的流浪动物救助站系统较少,所有很有必要开发一个轻量级的可以在网站上运行的流浪动物救助网站系统。4.2功能模块需求分析本网站最大的特点就功能全面,且结构简单用户在圈子信息框中,用户可以发布信息系统管理员:4.3设计的基本思想4.......
  • 总结篇:SpringBoot常用注解总结
    使用springboot开发的优点,就是不用部署war文件因为内部嵌入了tomcat的,允许通过maven来根据需要的starter,非常的方便,可以自动配置spring,为程序员减少大量时间用于写业务逻辑,更不用担心使用某个依赖的版本问题,springboot全部为你自己选择。springboot的常用注解:1、@SpringBootAppl......