【模式】AOP{更新中}

QGIS:安装Deepness插件+应用 简单的描述了deepness的安装应用历程,重点是记录博主本次遇到的坑 阅读详情

 

代理模式

代理模式的产生:明星A会唱歌,很多人都想找A商演,A自己不会。经纪人B,作为明星A的代理,负责接收邀请,筛选邀请,安排演唱前后接送,粉丝公关等事宜。明星A只负责唱歌就可以了。

代理模式:抽象一下,经纪人B 这群人就是ProxyClass-代理类,而明星A 这群人就是Class。ProxyClass类向外提供 Class 所有的方法(功能)。外部只需调用ProxyClass的方法,就可以让Class完成对应功能。ProxyClass 可以对调用前后进行控制。比如当有人调用ProxyClass的m1让明星A唱歌的时候,其对参数进行筛选,再调用 Class 的 m1 让明星A去赴演。

代理模式的设计类图:可以看到ProxyClass拥有Class的所有方法,并调用Class的方法。我想肯定有人会问,为什么还需要画蛇添足让两个类实现同一个接口。一是一种对外申明,Class有的接口ProxyClass全能代理。二是Class可以有很多个代理类,代理类都具有共同的代理接口,其次不需要修改现有依赖Class/ProxyClass的代码。

 

代理模式
代理模式设计类图

 

 

JDK动态代理

JDK动态代理的产生:

  • 被代理类方法特别多,代理类要做的事情雷同:假设 明星A 十项全能,有很多才艺。经纪人B 在接收邀请后做的事情却都是筛选。那么需要完全手写一个新的类,然后定义所有明星A拥有的方法。
  • 被代理类内容更改:再者随着时间的推移,A的技能在不断变化,B也又要随之修改,非常繁杂。
  • 代理类更换被代理类:假设 经纪人B 不想再给 明星A 代理了,换了另一个 运动明星C,则又得根据 明星C 修改 经纪人B 的代理方法。

本质想说明两点,普通的静态代理,也就是自己编写代理类:一个是代理类编写时的繁杂的重复,另一个是代理类ProxyClass 受到 被代理类Class 的变更的影响很大。

 

JDK动态代理的设计:

  • 供自定义方法模板:因为通常代理类的所有方法体都类似,因此不再定义一个代理类,只定义一个如下的方法模板即可。Java提供了一个java.lang.reflect.InvacationHandler接口,实现该接口的invoke方法,在方法体中写下述自定义模板。
do proxy stuff
call origin class's method like sing
do proxy stuff
  • 生成代理类:Java不是在编译时生成的类,而是在运行时生成类,Java提供了一个java.lang.reflect.Proxy类,类中有一个newInstance方法:Proxy.newInstance(类加载器ClassLoader,被代理的接口列表Class<?>[],自定义的方法模板InvocationHandler),返回一个为指定接口代理的代理对象。

 

JDK动态代理的使用:代码如下,我代理的是java.lang.Runnable接口。

package basics.proxy;


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author 100101001
 * @date 12/23/2019 10:18 AM
 */
public class jdk {

    private static int a = 123;    

    public static void main(String[] args) {
        Target t =new Target();
        //运行时生成类 Proxy$0 extends Proxy implements Runnable
        Runnable a = (Runnable) Proxy.newProxyInstance(Runnable.class.getClassLoader(), new Class[]{
                Runnable.class
        }, new InvocationHandler() { //这里采用了匿名类实现接口
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("jdk proxy before method..");
                method.invoke(t, args);
                System.out.println("jdk proxy after method..");
                //Runnable接口的run方法无返回值
                return null;
            }
        });
        new Thread(a).start();
    }

    //静态内部类等效于外部类,只不过类名jdk$Target
    //能访问jdk的所有静态变量和成员
    static class Target implements Runnable{
        @Override
        public void run() {
            System.out.println("target run"+a);
        }
    }
}

运行结果:

jdk proxy before method..
target run123
jdk proxy after method..

运行局部变量:a就是代理对象$Proxy0,其内部有一个h就是InvocationHnadler,因为它是jdk的一个匿名内部类,所以取类名 jdk$1,而t也是jdk的内部类Target(定义时)对象,所以取名 jdk$Target(可以和外部Target类区分,外部通过jdk.Target来访问该类)。

动态生成的代理类:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
 
public final class Proxy0
  extends Proxy
  implements Runnable
{
  // 在静态初始化代码块中使用反射获取Method
  // 比如 m3=Class.forName(java.lang.Runnable).getMethod("run", new Class[0])
  // h是构造Proxy时,传入的InvocationHandler
  // 在run方法体中直接 this.h.invoke(this, m3, null);
  private static Method m1;
  private static Method m3;
  private static Method m2;
  private static Method m0;
  
  public ProxySubject(InvocationHandler paramInvocationHandler)
  {
    super(paramInvocationHandler);
  }
  
  public final boolean equals(Object paramObject)
  {
    try
    {
      return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue();
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }
  
  public final void run()
  {
    try
    {
      this.h.invoke(this, m3, null);
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }
  
  public final String toString()
  {
    try
    {
      return (String)this.h.invoke(this, m2, null);
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }
  
  public final int hashCode()
  {
    try
    {
      return ((Integer)this.h.invoke(this, m0, null)).intValue();
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }
  
  static
  {
    try
    {
      m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });
      m3 = Class.forName("java.lang.Runnable").getMethod("run", new Class[0]);
      m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
      m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
      return;
    }
    catch (NoSuchMethodException localNoSuchMethodException)
    {
      throw new NoSuchMethodError(localNoSuchMethodException.getMessage());
    }
    catch (ClassNotFoundException localClassNotFoundException)
    {
      throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
    }
  }
}

 

AOP: Aspect-Oriented Programming

面向切面编程的产生:在OOP(Object-Oriented Progamming)中,方法都需要做一些共同的非功能性操作,比如对访问加锁,记录调用日志,异常处理。通过继承提供共同的操作,有单继承限制。因此,AOP产生了。我们把这些公共操作一一提炼成对应的代理模板(方法),组合到一个类中,这个类被称为切面(与继承垂直共享相对的一种横向共享的概念)。比如写一个日志切面类,定义实现两个代理模板方法,分别是开始计时(调用原方法前)和结束计时(调用原方法前)。这个日志切面类,记录了方法执行时间,方便优化分析,这些使用了切面功能的方法就是切入点。切面类似之前动态代理中的实现InvocationHandler的类,切入点类似之前的动态代理中的被代理的接口中的方法。类似这样的提炼公共操作,编写切面类,定义切入点的过程就是AOP。

 

面向切面编程的应用:这一部分参考了 简书作者:糖纸疯了 的文章 006--【SpringBoot】AOP使用集锦,web应用框架往往会使用AOP实现功能模块(比如框架提供对Controller类所有方法返回值序列化这一公共操作,开发者无需自行编写),向外提供AOP工具(比如在SpringBoot中提供AOP注解,允许用户自定义切面)。

这里自定义接口日志切面效果如下。在接口执行前,记录了接口方法,接口所在类,接口参数,接口URL等信息,执行后,记录了返回值类型。

日志效果图

在SpringBoot中,自定义Aspect的方法如下。

  • Aspect注解切面类
  • 切面类内PointCut注解方法指明代理的方法
  • Before,After,AfterReturning,AfterThrowing,Around等指明切面在方法执行的流程中代做的事情
@Aspect
@Component
public class LogWebAspect {
    //统计请求的处理时间
    ThreadLocal<Long> startTime = new ThreadLocal<>();
    /**
     * 指定切点
     * 匹配 com.enzoism.controller包及其子包下的所有类的所有方法
     */
    @Pointcut("execution(public * com.enzoism.controller.*.*(..))")
    public void webLog(){
    }

    /**
     * 前置通知,方法调用前被调用
     * @param joinPoint
     */
    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint){
        System.out.println("我是前置通知!!!");
        startTime.set(System.currentTimeMillis());
        //获取目标方法的参数信息
        Object[] obj = joinPoint.getArgs();
        System.out.println("请求参数:"+obj);
        // 代理
        Signature signature = joinPoint.getSignature();
        //代理的是哪一个方法
        System.out.println("方法:"+signature.getName());
        //AOP代理类的名字
        System.out.println("方法所在包:"+signature.getDeclaringTypeName());
        //AOP代理类的类(class)信息
        signature.getDeclaringType();
        MethodSignature methodSignature = (MethodSignature) signature;
        String[] strings = methodSignature.getParameterNames();
        System.out.println("参数名:"+ Arrays.toString(strings));
        System.out.println("参数值ARGS : " + Arrays.toString(joinPoint.getArgs()));
        // 接收到请求,记录请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest req = attributes.getRequest();
        // 记录下请求内容
        System.out.println("请求URL : " + req.getRequestURL().toString());
        System.out.println("HTTP_METHOD : " + req.getMethod());
        System.out.println("IP : " + req.getRemoteAddr());
        System.out.println("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());

    }

    /**
     * 处理完请求返回内容
     * @param ret
     * @throws Throwable
     */
    @AfterReturning(returning = "ret", pointcut = "webLog()")
    public void doAfterReturning(Object ret) throws Throwable {
        // 处理完请求,返回内容
        System.out.println("方法的返回值 : " + ret);
    }

    /**
     * 后置异常通知
     * @param jp
     */
    @AfterThrowing("webLog()")
    public void throwss(JoinPoint jp){
        System.out.println("方法异常时执行.....");
    }

    /**
     * 后置最终通知,final增强,不管是抛出异常或者正常退出都会执行
     * @param jp
     */
    @After("webLog()")
    public void after(JoinPoint jp){
        System.out.println("方法执行时间:"+ (System.currentTimeMillis() - startTime.get()));
        System.out.println();
    }

    /**
     * 环绕通知,环绕增强,相当于MethodInterceptor
     * @param pjp
     * @return
     */
    @Around("webLog()")
    public Object arround(ProceedingJoinPoint pjp) {
        try {
            Object o =  pjp.proceed();
            return o;
        } catch (Throwable e) {
            e.printStackTrace();
            return null;
        }
    }
}

切面除了可以应用到某个包下的所有类中的所有方法,还可以指定应用于某个注解??待更新

@Aspect
@Component
public class LogAnnotationAspect {
    /**
     * 指定切点
     * 匹配 被添加LogAnnotation标注的方法
     */
    @Pointcut("@annotation(logAnnotation)")
    public void pointCut(LogAnnotation logAnnotation) {
    }

    /**
     * 环绕通知,环绕增强,相当于MethodInterceptor
     * @param pjp
     * @return
     */
    @Around("pointCut(logAnnotation)")
    public Object arround(ProceedingJoinPoint pjp, LogAnnotation logAnnotation) {
        try {
            Object o = pjp.proceed();
            System.out.println("---------------直接指定到logAnnotation位置");
            System.out.println("actionType:"+logAnnotation.actionType());
            System.out.println("controllerName:"+logAnnotation.controllerName());
            System.out.println("module:"+logAnnotation.module());
            return o;
        } catch (Throwable e) {
            e.printStackTrace();
            return null;
        }
    }
}

 

YOLOv8 交通管理三大核心功能 —— 二、违章检测系统 详细解释及代码完整示例 YOLOv8交通违章检测系统 阅读详情

相关推荐

海康工业相机使用:常见问题及解决方法

工业相机在使用过程中,经常会因为操作不当、使用环境不当等原因出现一些问题,本篇教程,主要针对海康工业相机常见问题及其定位方法做以简单介绍,希望可以帮助大家。 注:该教程对其他品牌工业相机“常见问题”排查,也具备一定的指导意义。 当出现无法通过客户端发现设备或者无法预览图像等问题,先确认当前的运行环境是否满足以下要求: 确认装有相机驱动软件的电脑网卡为千兆网卡(Gige接口相机); 确认网卡是否已开启巨型帧; 确认电脑与网口相机之间的网络链路为千兆; 确认装有相机驱动软件的USB接口为3...

Cche的博客 3万+

面试中关于Spring AOP和代理模式的那些事

我们知道,Spring 中 AOP 是一大核心技术,也是面试中经常会被问到的问题,最近我在网上也看到很多面试题,其中和 Spring AOP 相关的就有不少,这篇文章主要来总结下相关的技术点,希望对大家有用。 0. 几个常见的问题 针对这一块的东西,一般下面几个问题面试官问的比较多: Spring AOP用的是哪种设计模式? 谈谈你对代理模式的理解? 静态代理和动态代理有什么区别? 如何实现动态...

1万+

Ansys HFSS 中的同轴电缆仿真

准确模拟它们的行为对于确保 RF 系统的最佳性能至关重要。在本博客中,我们将介绍在 HFSS 中设置同轴电缆仿真并绘制插入损耗、回波损耗和电场分布的过程。将波端口分配给同轴线的两端以激励模型,并定义了从 1 GHz 到 20 GHz 的频率扫描以评估其宽带性能。铜分配给内部导体,铝分配给外部导体。介电区域使用 PTFE 定义,其相对介电常数为 2.1,损耗角正切为 0.00022。仿真完成后,结果用于绘制整个频率范围内的回波损耗和插入损耗。此外,电介质内的电场分布也被绘制和动画化。

jkh920184196的博客 1907

springboot update数据_SpringCloud或SpringBoot+Mybatis-Plus利用AOP+mybatis插件实现数据操作记录及更新对比...

引文本文主要介绍如何使用Spring AOP + mybatis插件实现拦截数据库操作并根据不同需求进行数据对比分析,主要适用于系统中需要对数据操作进行记录、在更新数据时准确记录更新字段核心:AOP、mybatis插件(拦截器)、mybatis-Plus实体规范、数据对比1、相关技术简介mybatis插件:mybatis插件实际上就是官方针对4层数据操作处理预留的拦截器,使用者可以根据不同的需求进...

weixin_29513805的博客 2609

YOLOv12改进策略【独家融合改进】| MobileNetV4+BiFPN,轻松实现降参涨点,适用专栏内所有的骨干替换

可扩展的高效物体检测BiFPN(加权双向特征金字塔网络)

Limiiiing的博客 978

01 - 什么是SVM

摘要:SVM(共享虚拟内存)技术使CPU和GPU能共享同一虚拟地址空间,简化异构计算编程。传统模型需手动管理CPU/GPU内存和拷贝数据,而SVM允许直接传递指针,自动处理页面迁移和一致性维护。其核心包括统一地址空间、按需迁移、页面故障处理和一致性管理,显著降低编程复杂度并提升性能。通过HMM框架、MMU通知和GPU页面异常等机制实现高效内存共享,支持复杂数据结构,为异构计算带来便利。

图形/计算GPU的驱动与虚拟化技术分享园地 3118

代理模式和Spring的AOP(持续更新)

代理模式 代理模式为SpringAOP的底层实现,分为静态代理和动态代理 角色分析: 抽象角色:使用接口或者抽象类 真实角色:被代理的角色 代理角色:代理真实角色,代理后增加一些附属操作 客户访问代理角色的人 静态代理 用三个角色(客户、房屋中介、房东)来介绍静态代理 编写Rent(出租)接口 (抽象角色) package com.zhbit.demo01; //租房 public inter...

HONHoChi的博客 230

睿抗机器人魔力元宝在完成任务过程中如何使机械臂先到达白色盒子上方而不是先到达工作台?

🏆 本文收录于《全栈Bug调优(实战版)》专栏,致力于分享我在项目实战过程中遇到的各类Bug及其原因,并提供切实有效的解决方案。无论你是初学者还是经验丰富的开发者,本文将为你指引出一条更高效的Bug修复之路,助你早日登顶,迈向财富自由的梦想🚀!同时,欢迎大家关注、收藏、订阅本专栏,更多精彩内容正在持续更新中。让我们一起进步,Up!Up!Up!    备注: 部分问题/难题源自互联网,经过精心筛选和整理,结合数位十多年大厂实战经验资深大佬经验总结所得,数条可行方案供所需之人参考。

**My Coding Family** 1376

观察者模式+AOP 代码示例

背景 当经纪人创建客户时,需要给对应的经纪人增加战报信息。在代码层面上,客源的相关类只针对客源数据表操作。而战报信息包含了多种业务统计数据,客源只是其中统计的部分数据。鉴于两者相对独立,且客源的战报信息会有所修改。因此,采用AOP+观察者模式构建代码。 代码 定义一个注解,用于AOP拦截。 /** * 战报注解 */ @Retention(RetentionPolicy.RUNTIME) @T...

weixin_34209406的博客 193

【k8s故障处理篇】calico-node启动失败“Felix is not live: Get “http://localhost:9099/liveness” 解决办法(V1.30.3版本)

【k8s故障处理篇】calico-node启动失败“Felix is not live: Get “http://localhost:9099/liveness” 解决办法(V1.30.3版本)

jks212454的博客 1090

如何通过 Python 爬虫抓取并分析政府开放数据

通过本文的介绍,我们展示了如何使用Python 爬虫抓取并分析政府开放数据。通过requests获取政府开放数据的 API 接口数据。使用和pandas进行数据清洗与存储。使用matplotlib对数据进行可视化。你可以根据不同的政府开放平台和数据集进行调整,应用于不同领域的数据分析,如公共健康、交通、环保等。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1076

C++11 设计模式--模板方法模拟实现Java Spring AOP

目录一:背景二:具体实现三:应用 一:背景 当进行数据库更新的时候,有以下场景需要处理: 1:业务方法执行开始的时候,需要拿到数据库连接,然后开启事务。 2:若业务在某个环节抛异常,为了数据库数据的而一致性,需要回滚事务。3:若业务执行无异常,需要提交事务。 4:最后无论业务成功或者失败,都需要释放资源。 对于这个业务场景,Java Spring框架的AOP可以很方便的对业务方法做拦截处理。Java动态代理也能很方便的实现该需求。而C++没有相对应的特性。本文模仿Java AOP,基于设计模式中的模板方法,

qq_39519014的博客 923

基于物联网技术设计的微型消防小车控制系统(STM32+ESP8266局域网)(181)

基于物联网技术的小微型消防车控制系统。通过远程控制功能,用户能够灵活操作消防车的行驶,方便快速抵达火灾现场。环境感知功能实时采集烟雾浓度、温湿度信息,为灭火决策提供科学依据。火源定位功能采用自动和手动两种模式,准确迅速地定位火源,并通过报警提示用户。灭火功能则根据火源定位结果,自动或手动启动干粉灭火器进行高效灭火。这些功能的结合实现了对小型火灾的全面应对,提升了消防效率与安全性,减少了火灾带来的损失。通过本项目的设计与实现,为消防领域提供了一种创新且实用的解决方案。

3079

【数据库】如何使用一款轻量级数据库SqlSugar进行批量更新,以及查看最终的Sql操作语句

最近在使用SqlSugar这个第三方ORM框架,时间久了很多用法就容易忘记,可能也是博主上了年纪有些用法忘得快,哈哈哈。 所以,AI应用的出现,绝对是我们程序员的绝佳助手,我们可以不用记住太多的太细的知识点,把基本原理和底层架构掌握好,剩下就交给AI。

小5聊的博客 3696

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

【.NET中AOP的实现方案】静态代理

Spring AOP 应该是比较出名的了,今天说的是C#里的AOP,C#的AOP实现的方式有很多种,现在就先介绍静态代理的实现方案; 模拟场景:我们在删除用户,或者更新用户的时候进行数据原始备份,这样的话需要在删除操作进行之前进行一些数据相应的操作,但是我们又不想在删除操作里面做一些与删除无关的操作,这样使用AOP就解决这个问题了;更新操作也一样。 下面是示例代码(省略引用): 1、首先是实...

Mr_Tank_ 360

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

谈谈MVC、MVVM、MVP、AOP的区别

今天我们来谈谈 MVC、MVVM、MVP和 AOP 的区别。这些概念分属不同层级:MVC/MVVM/MVP 是架构模式,用于组织代码结构;AOP 是编程范式,解决横切关注点的问题。

xyphf的博客 1168

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

AspectJ实现设计模式(一)——观察者模式

  观察者模式是GOF中所介绍的一种常用的设计模式,本文将介绍使用AspectJ利用AOP来实现观察者模式,并通过一个简单的示例说明它的用法。    以下是AOP实现观察者模式的UML图在AOP版本中,Subject和Observer接口的成员将由抽象方面ObserverProtocol实现,而其中最关键的一点是抽象pointcut stateChange,它将由具体子方面根据不同的应

starchu1981的专栏 1737

ORM数据层框架的设计热点:更新指定的列的几种设计方案

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34258838的博客 159

代理模式(Spring Aop详解)

1.1 概述 代理(Proxy)是一种设计模式, 提供了对目标对象另外的访问方式;即通过代理访问目标对象。 这样好处: 可以在目标对象实现的基础上,增强额外的功能操作。(扩展目标对象的功能)。 举例:明星(邓紫棋)ß---经纪人<-------用户 目标 (代理) 代理模式的关键点: 代理对象与目标对象。 1.2 静态代理 静态代理, 1) 代理对象,要实现与目标对象一样的接口; ...

嘉会的博客 379

AOP.jsp+MVC.jsp

实现页面的aop和mvc模式一 : aop.jsp<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <html> <head> <script type="text/javascript" src="<%=request.getContextPath() %>/scripts/jquery-1.8.3.js">

Celebrity_Senior的博客 587

Nepxion Matrix AOP框架介绍

Nepxion Matrix AOP框架介绍 Nepxion Matrix 是一个开源的AOP(面向切面编程)框架,它主要使用Java编程语言开发。该框架与Spring框架紧密集成,提供了Spring AutoProxy、Spring Registrar和Spring Import Selector三种机制的整合,具备高度的通用性、健壮性、灵活性和易用性。 项目基础介绍 Nepxion Matri...

gitblog_00299的博客 452

007 - Spring框架中都用到了哪些设计模式?

可以通过首词法来记住Spring框架使用的一些设计模式:观单模代工(含义为观察单个模特代工)。 1、观察者模式:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知,被自动更新,例如:ApplicationListener。 2、单例模式:Bean默认为单例模式。 3、模板方法模式:用来解决代码重复的问题,以 Template 结尾的类基本都是。比如:RestTemplate、JdbcmsTemplate等。 4、代理模式:Spring的AOP功能用到了JDK的.

Zebe 490

JetCache源码解析——缓存处理

在Java技术体系中,如果想要在不改变已有代码逻辑的情况下,对已有的函数进行功能增强,一般可以使用两种方式,如AOP(Aspect Oriented Programming),即面向切面编程,以及代理模式,如使用JDK 动态代理或 CGLIB 动态代理。例如Mybatis的源码中同时使用了JDK 动态代理或 CGLIB 动态代理,但是对于Mapper接口是使用JDK动态代理模式。

qq_16500963的博客 3374

AspectJ实现设计模式(一)——观察者模式 (转)

AspectJ实现设计模式(一)——观察者模式 (转)[@more@] 观察者模式是GOF中所介绍的一种常用的设计模式,本文将介绍使用ASPectJ利用AOP来实现观察者模式,并通过一个简单的示例说明它的用法。 以下是A...

cuiji1279的博客 190

AOP+注解方式记录、打印请求信息

应对场景 在一些项目中,会有这样的一个场景,对某个接口所接受到的所有请求,进行入库记录,并记载该次请求的状态(成功与否),或业务中涉及任务时,也需要对该任务进行入库记录甚至跟踪。 最简单的实现方式,是在controler层接收到请求后,解析入参并入库保存请求(任务)信息,service层处理完逻辑后再解析返回并更新任务信息。 但这只是一次顺利的请求并成功返回的场景,如果接口返回失败,或在service层的任意地方发生异常、err,都让任务的数据库更新操作很难完成。当然,应对代码抛出异常的问题,结合全局参数异

weixin_42049458的博客 921

Spring Boot AOP 拦截器链设计方案

拦截器链的核心是通过责任链模式将多个拦截器串联起来,每个拦截器负责处理特定的逻辑。在现代Java开发中,Spring Boot的AOP(面向切面编程)为开发者提供了强大的拦截能力,能够在不侵入业务代码的情况下实现日志记录、权限校验、事务管理等横切关注点。拦截器链的调用通过ReflectiveMethodInvocation实现,它会按顺序执行链中的拦截器。通过以上设计,Spring Boot AOP拦截器链能够以低耦合、高灵活性的方式满足多样化需求,成为企业级开发中不可或缺的利器。

bmjner_102的博客 212
上一篇: 【图】最小生成树{更新中}
下一篇: 【设计模式】访问者模式{更新中}
vectorX
博客等级 码龄11年 37粉丝 21原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值