Spring AOP 的实现方式(以日志管理为例)

Spring MVC中基于AOP注解的日志管理实现详解 在Spring AOP的实际开发中,构建一个功能完整且可维护的切面类是实现横切关注点(如日志、权限校验、性能监控)的基础。本章将围绕@Aspect和@Component这两个核心注解展开,深入剖析如何通过它们协同工作来创建并注册切面组件,并进一步探讨其生命周期管理、执行顺序控制以及启用机制。理解这些内容对于构建高内聚、低耦合的企业级AOP模块至关重要。最佳实践是将通用切入点集中在一个专门的切面类中:@Aspect@Component其他切面可通过全限定名引用:@Aspect。 阅读详情

1.为什么需要AOP

假如我们应用中有n个业务逻辑组件,每个业务逻辑组件又有m个方法,那现在我们的应用就一共包含了n*m个方法,我会抱怨方法太多。。。现在,我有这样一个需求,每个方法都增加一个通用的功能,常见的如:事务处理,日志,权限控制。。。最容易想到的方法,先定义一个额外的方法,实现该功能,然后再每个需要实现这个功能的地方去调用这个额外的方法。这种做法的好处和坏处分别是。
好处:可以动态地添加和删除在切面上的逻辑而不影响原来的执行代码。
坏处:一旦要修改,就要打开所有调用到的地方去修改。
好,现在我们用AOP的方式可以实现在不修改源方法代码的前提下,可以统一为原多个方法增加横切性质的“通用处理”。

2.什么是AOP

AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善。本文提供Spring官方文档出处:https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#aop-api

从官方文档上摘抄的解释就是:面向方面编程(AOP)是面向对象编程(OOP)补充的另一种提供思考程序结构补充。在OOP中模块化的关键单元是类,而在AOP模块的单位是一个方面。面对关注点,如事务管理跨越多个类型和对象切模块化。(这些关注经常被称为在AOP文学横切关注点。)
相关概念(只需做个大概的了解就好)

Aspect:这横切多个对象关心的模块化。事务管理是企业Java应用程序的横切关注点的一个很好的例子。在SpringAOP中,切面可以使用类(基于模式)或@Aspect注解(@AspectJ风格)注解普通班实施。

Join point:程序在执行过程中的一个点,如方法的执行或异常的处理。在SpringAOP中,一个连接点总是代表一个方法的执行。

Advice:在切面的某个特定的动作连接点。不同类型的意见,包括 "around," "before" and "after"的advice。(通知的类型将在下面讨论)。许多AOP框架,包括Spring都是以拦截器作为通知模型,去维护一条围绕着一个连接点的拦截器链。

Pointcut:匹配连接点的断言。通知是跟一个切入点表达式,并在运行在切入点匹配的连接点相关联(例如,一个方法的执行要有一个确定的名字)。切入点表达式作为匹配的连接点的概念是重要的对AOP和Spring缺省使用AspectJ切入点表达式语言。

Introduction:声明代表的类型的额外的方法或字段。 Spring允许引入新的接口(以及一个对应的实现)到任何被代理的对象。例如,你可以使用引入来使一个bean实现IsModified接口,以便简化缓存。 (介绍被誉为AspectJ的社会类型间的声明。)

Target object:对象由一个或多个方面被建议。也被称作被通知对象。既然Spring AOP是通过运行时代理实现的,这个对象永远是一个被代理对象。

AOP proxy:AOP框架,以实现切面契约(例如通知方法执行等等)创建的对象。在Spring中,AOP代理可以是JDK动态代理或者CGLIB代理。

Weaving:与连接其他应用程序类型或对象方面来创建一个被通知的对象。这是可以做到在编译时(使用AspectJ编译器,例如),加载时间,或在运行时。 Spring AOP中,像其他纯Java AOP框架,在运行时进行编织。

那问题来了,AOP是在什么时候去改我们的代码的?即给我们加上额外的横切性质的"通用处理"的?

两个时机:

  1. 在编译java源代码的时候 ----编译时增强
  2. 在运行时动态地修改类 ----运行时增强(动态代理)

我们的Spring的AOP的实现原理就是基于动态代理。

3.Spring AOP的3种实现方式

对于框架的学习,我觉得得先会用,然后再深入原理。关于SpringAOP的实现我在这里划分成3个方式(以日志管理为例)废话不多说,直接上代码了。

配置之前注意配置文件要加上命名空间:xmlns:aop="http://www.springframework.org/schema/aop"

1.基于xml配置的实现

spring-mvc.xml

<!-- 使用xml配置aop -->
        <!-- 强制使用cglib代理,如果不设置,将默认使用jdk的代理,但是jdk的代理是基于接口的 -->
        <aop:config proxy-target-class="true" />  
        <aop:config>
        <!--定义切面-->
        <aop:aspect id="logAspect" ref="logInterceptor">
        <!-- 定义切入点 (配置在com.gray.user.controller下所有的类在调用之前都会被拦截)-->
        <aop:pointcut expression="execution(* com.gray.user.controller.*.*(..))" id="logPointCut"/>
        <!--方法执行之前被调用执行的-->
        <aop:before method="before" pointcut-ref="logPointCut"/><!--一个切入点的引用-->
        <aop:after method="after" pointcut-ref="logPointCut"/><!--一个切入点的引用-->
        </aop:aspect>
        </aop:config>

LogInterceptor.java

package com.gray.interceptor;
 
import org.springframework.stereotype.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
@Component
public class LogInterceptor {
    private final Logger logger = LoggerFactory.getLogger(LogInterceptor.class);
    public void before(){
        logger.info("login start!");
    }
    
    public void after(){
        logger.info("login end!");
    }
}

在这里我没有配bean是因为我在之前的配置文件里面写了自动扫描组件的配置了
要加入日志管理逻辑的地方

@RequestMapping("/dologin.do") //url
public String dologin(User user, Model model){
    logger.info("login ....");
    String info = loginUser(user);
    if (!"SUCC".equals(info)) {
        model.addAttribute("failMsg", "用户不存在或密码错误!");
        return "/jsp/fail";
    }else{
        model.addAttribute("successMsg", "登陆成功!");//返回到页面说夹带的参数
        model.addAttribute("name", user.getUsername());
        return "/jsp/success";//返回的页面
    }
  }

2.基于注解的实现
spring-mvc.xml

<aop:aspectj-autoproxy proxy-target-class="true">
</aop:aspectj-autoproxy>

LogInterceptor.java

@Aspect
@Component
public class LogInterceptor {
    private final Logger logger = LoggerFactory.getLogger(LogInterceptor.class);
    @Before(value = "execution(* com.gray.user.controller.*.*(..))")
    public void before(){
        logger.info("login start!");
    }
    @After(value = "execution(* com.gray.user.controller.*.*(..))")
    public void after(){
        logger.info("login end!");
    }

要加入逻辑的地方同上。
3.基于自定义注解的实现
基于注解,所以spring-mvc.xml也是和上面的一样的。

LogInterceptor.java(这里我只加入前置日志)

package com.gray.interceptor;
 
import java.lang.reflect.Method;
 
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
 
import com.gray.annotation.Log;
 
@Aspect
@Component
public class LogInterceptor {
    private final Logger logger = LoggerFactory.getLogger(LogInterceptor.class);
 
    @Pointcut("@annotation(com.gray.annotation.Log)")    
    public void controllerAspect() {
        
    }
    @Before("controllerAspect()")
    public void before(JoinPoint joinPoint){
        logger.info(getOper(joinPoint));
    }
    private String getOper(JoinPoint joinPoint) {
        MethodSignature methodName = (MethodSignature)joinPoint.getSignature();
        Method method = methodName.getMethod();
        return method.getAnnotation(Log.class).oper();
    }
}

同时,加入逻辑的地方需要加入Log注解

@RequestMapping("/dologin.do") //url
@Log(oper="user login")
public String dologin(User user, Model model){
    logger.info("login ....");
    String info = loginUser(user);
    if (!"SUCC".equals(info)) {
        model.addAttribute("failMsg", "用户不存在或密码错误!");
        return "/jsp/fail";
    }else{
        model.addAttribute("successMsg", "登陆成功!");//返回到页面说夹带的参数
        model.addAttribute("name", user.getUsername());
        return "/jsp/success";//返回的页面
    }
  }

常见的基于注解的方式除了before和after,还有around和AfterThrowing等,在做第三种方式实验的时候还遇到这种错误:error at ::0 can't find referenced pointcut。我的解决办法是:因为我的jdk是1.7,与原来在pom.xml中配的那个aspectjweaver的jar包版本不匹配,所以我需要升级,由1.5.4改成1.7.4。

无人机开发平台全解析:从开源飞控到企业级应用实战指南 无人机开发平台是无人机从飞行器演变为智能空中机器人的核心,其本质是提供了一套标准化的软硬件接口与工具链,使开发者能够基于稳定可靠的底层系统,专注于上层应用创新。从技术原理上看,一个完整的开发平台通常包含飞行控制器、机载计算机、传感器套件等硬件层,以及飞控固件、机器人操作系统(ROS/ROS 2)、软件开发套件(SDK)等软件层,通过分层架构实现飞行控制、感知决策与任务执行的解耦。其技术价值在于大幅降低了无人机行业应用的开发门槛,使开发者无需从零构建飞行控制系统,即可快速实现自动巡检、精准农业、物流配送等复杂 阅读详情

相关推荐

基于NE555的触摸延时开关电路设计与实现

本文详细介绍了基于NE555芯片的触摸延时开关电路设计与实现方法。通过分析NE555的单稳态工作模式,结合定时电阻、电解电容等关键元件选型,提供了一套完整的电路搭建方案。文章还包含抗干扰设计、调试技巧及常见故障处理,帮助电子爱好者快速掌握触摸延时灯的制作要点。

weixin_29268267的博客 788

@Aspect 注解使用详解

AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。 在spring AOP中业务逻辑仅仅只关注业务本身,将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑

weixin_44026997的博客 788

win11下的MySQL安装

目前官方最新版本是8.0.26,考虑到其稳定性、可靠性还需一定周期保证,所以使用官方版求稳定仍然建议5.7系列。3、选择MySQL Servers 5.7.38 -x64,然后按绿色箭头将选中的版本移植到右边选中框中。4、点击下方蓝色Advanced Options,选择安装位置。1、在开始界面搜索MySQL,点击command line。4、在“系统变量”中选择“path”,点击编辑。5、新建——>增加MySQL路径——>确定,12、execute,安装好后next。9、不需要做修改,直接点击next。.

rensweet的博客 2万+

Spring中Aop实现日志功能

Spring中实现aop自定义注解实现日志功能。

qq_37400096的博客 2500

YOLOv11 改进 - 检测头 | Detect_LSCD轻量共享卷积检测头:轻量化设计破解计算瓶颈,增强复杂场景目标感知能力

本文介绍了基于群归一化(GroupNorm)和共享卷积的轻量化检测头LSCD,并将其集成进YOLOv11。LSCD检测头充分利用了GroupNorm和共享卷积的优势,在保持特征信息有效融合的同时,减少计算量和运算复杂度。我们将LSCD的代码集成到YOLOv11检测头中,并在tasks文件中进行注册。实验证明,YOLOv11-LSCD在目标检测任务中取得了良好的效果。

魔改工程师的博客 2390

基于Verilog的8位CPU设计及UART扩展实现方案,包含完整的架构设计、核心代码实现和仿真验证方法

基于Verilog的8位CPU设计及UART扩展实现方案,包含完整的架构设计、核心代码实现和仿真验证方法

a_zxswer的博客 190

spring AOP实现日志管理

前言 spring AOP是使用spring提供的切面来横向拓展项目,使得一些和主业务无关的操作尽可能实现解耦,比如说我们经常使用的日志。 注: 需要用到pom文件 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> 实操 1、编写一个自

haiboSun的博客 5767

FLUENT Meshing Watertight Geometry工作流入门 - 9 生成体网格

总结一下我们学到的东西。讨论体积网格的重要性,并了解生成体积网格的不同方法。还了解体积网格质量的重要性,并学习如何改进它。

B_etter_Man的博客 1万+

SpringAOP详解+使用aop完成添加日志

AOP(Aspect Oriented Programming)面向切面思想,是Spring的三大 核心思想之一(AOP-面向切面、IOC-控制反转、DI-依赖注入)。AOP,一般称为面向切面,作为面向对象OOP的一种补充,用于将那 些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取并 封装为一个可重用的模块,这个模块被命名为“切面”(Aspect),减少 系统中的重复代码,降低了模块间的耦合度,提高系统的可维护性。可用于权限认证日志事务处理。定义自定义注解。

不惧困难 顽强拼搏 1953

4、接收天线:接收电压、功率和传输系数

本文详细探讨了接收天线的性能参数,包括接收电压、功率和传输系数,通过建立等效电路模型分析接收偶极子的电流和开路电压,并定义电压和功率传输函数。研究揭示了天线长度、工作频率及极化失配对传输性能的影响,并提出了优化接收天线性能的策略,为天线系统的设计与优化提供了理论支持。

ll5678的博客 233

EDEM-FLUENT耦合报错几大原因总结(持续更新)

EDEM-FLUENT耦合报错几大原因总结(持续更新)

zheaa的博客 2761

SpringAop日志管理实现方式

1、Aop切面注解: 1.1@Aspect注解将一个Java类定义为切面类; 1.2@Pointcut定义一个切入点,可以是一个表达式,例:package下的所有函数,也可是一个注解; 根据切入点的不同位置切入内容 1.3@Before在切入点开始处切入内容; 1.4@After在切入点的结尾处切入内容; 1.5@AfterReturning在切入点return内容之后切入内容 1....

你能找到这里,说明你有经天纬地之才,扭转乾坤只能,鬼神不测之计包藏宇宙之志,真乃乱世之枭雄,治世之能臣也 986

【Nginx学习】5步揭秘Nginx邮件代理模块:邮件代理服务器的功能与实现

Nginx的邮件代理模块(Mail Proxy Module)允许Nginx作为邮件代理服务器,支持SMTP、POP3和IMAP协议。这使得Nginx可以作为一个高性能的邮件网关,用于过滤垃圾邮件、病毒扫描、负载均衡等任务。简单来说,Nginx在这里就像是一个邮递员,负责将邮件从发件人手中安全、快速地送到收件人手中。通过上述的解析,我们可以看到Nginx在邮件代理模块中的设计和实现。从配置解析、连接处理,到协议处理、SSL/TLS加密和日志记录,每一步都至关重要。

java专栏 1314

Spring之Aop浅谈第1种配置实现方式

Aop的讲解,面向切面编程,spring之Aop,Aop实例开发

奶厂小程的博客 419

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Spring面试系列-01

Spring中文翻译过来是春天的意思,被称为J2EE的春天,是一个开源的轻量级的Java开发框架, 具有控制反转(IoC)和面向切面(AOP)两大核心。Java Spring框架通过声明式方式灵活地进行事务的管理,提高开发效率和质量。Spring框架不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何 Java 应用都可以从Spring中受益。Spring框架还是一个超级粘合平台,除了自己提供功能外,还提供粘合其他技术和框架的能力。1)IOC 控制反转。

baidu_36611723的博客 160

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

基于SpringBoot使用AOP技术实现操作日志管理

操作日志对于程序员或管理员而言,可以快速定位到系统中相关的操作,而对于操作日志的管理的实现不能对正常业务实现进行影响,否则即不满足单一原则,也会导致后续代码维护困难,因此我们考虑使用AOP切面技术来实现对日志管理的实现。 文章大致内容: 1、基本概念 2、基本应用 3、日志管理实战 对这几部分理解了,会对AOP的应用应该很轻松。 一、基本概念 项目 描述 Aspect(切面) ...

伍婷的专栏 7048

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

Spring AOP实现日志管理

😔记录一下Spring AOP的日志管理实现。

Pompey_wp的博客 1116

spring boot 使用AOP实现日志管理

Spring Boot的AOP(Aspect Oriented Programming,面向切面编程)是一种编程思想和技术,旨在通过将应用程序的功能分割成多个独立的模块来提高代码的可维护性和可重用性。AOP可以帮助我们跨多个类和模块提取和封装应用程序中重复的代码逻辑,例如日志记录、性能监控、安全检查等。它通过定义一个切面(Aspect),在代码中就是使用@Aspect注解,将这些横跨多个类的共同关注点(即横切关注点)从主要业务逻辑中分离出来。

m0_61569140的博客 1378

Spring Aop 日志管理

<br />Spring Aop 日志管理<br />Spring 带给我们的另一个好处就是让我们可以“专心做事”,下面我们来看下面一个例子:<br />public void doSameSomesing(int age,String  name){<br />     // 记录日志<br />     log.info("调用doSameSomesing方法,参数是:"+agfe+” ”+name);<br />     // 输入合法性验证<br />     if (age<=0){<br /> 

java傻瓜式教程 8466

Spring AOP拦截Service实现日志管理(自定义注解的方式)

最近项目中用到AOP方式进行Service操作方法日志管理,特为之记! 1、先说理论和采用的方法 采用注解的方式,其中包括以下注解:@Aspect(类注解)和@AfterReturning(方法注解),其中需要用的Maven库如下: "org.aspectj:aspectjrt:1.8.9", "org.aspectj:aspectjweaver:1.8.9", org.spring

tongxinxiao的专栏 5569
上一篇: Optional避免空指针的用法
下一篇: Java8 接口的默认方法和静态方法
小许子是逗星人
博客等级 码龄11年 2粉丝 24原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值