Spring AOP实现原理详解之Cglib代理实现

CGLIB和AOP 1. CGLIB 1.1 CGLIB简介 CGLib (Code Generation Library) 是一个强大的、高性能、高质量的 Code 生成类库。它可以在运行期扩展 Java 类与实现 Java 接口。CGLib 比 Java 的 java.lang.reflect.Proxy 类更强的在于它不仅可以接管接口类的方法,还可以接管普通类的方法。 1.2 案例 步骤: 1.创建springboot项目 2.导入相关依赖 3.创建实体类 @Component public class Book 阅读详情

引入

我们在前文中已经介绍了SpringAOP的切面实现和创建动态代理的过程,那么动态代理是如何工作的呢?本文主要介绍Cglib动态代理的案例和SpringAOP实现的原理。

要了解动态代理是如何工作的,首先需要了解

  • 什么是代理模式?
  • 什么是动态代理?
  • 什么是Cglib?
  • SpringAOP和Cglib是什么关系?

动态代理要解决什么问题?

什么是代理?

代理模式(Proxy pattern): 为另一个对象提供一个替身或占位符以控制对这个对象的访问

举个简单的例子:

我(client)如果要买(doOperation)房,可以找中介(proxy)买房,中介直接和卖方(target)买房。中介和卖方都实现买卖(doOperation)的操作。中介就是代理(proxy)。

什么是动态代理?

动态代理就是,在程序运行期,创建目标对象的代理对象,并对目标对象中的方法进行功能性增强的一种技术。

在生成代理对象的过程中,目标对象不变,代理对象中的方法是目标对象方法的增强方法。可以理解为运行期间,对象中方法的动态拦截,在拦截方法的前后执行功能操作。

什么是Cglib? SpringAOP和Cglib是什么关系?

Cglib是一个强大的、高性能的代码生成包,它广泛被许多AOP框架使用,为他们提供方法的拦截。

  • 最顶层是字节码,字节码相关的知识请参考 JVM基础 - 类字节码详解
  • ASM是操作字节码的工具
  • cglib基于ASM字节码工具操作字节码(即动态生成代理,对方法进行增强)
  • SpringAOP基于cglib进行封装,实现cglib方式的动态代理

Cglib代理的案例

这里我们写一个使用cglib的简单例子。@pdai

pom包依赖

引入cglib的依赖包

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>tech-pdai-spring-demos</artifactId>
        <groupId>tech.pdai</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>007-spring-framework-demo-aop-proxy-cglib</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/cglib/cglib -->
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>3.3.0</version>
        </dependency>
    </dependencies>

</project>

定义实体

User

package tech.pdai.springframework.entity;

/**
 * @author pdai
 */
public class User {

    /**
     * user's name.
     */
    private String name;

    /**
     * user's age.
     */
    private int age;

    /**
     * init.
     *
     * @param name name
     * @param age  age
     */
    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

被代理的类

即目标类, 对被代理的类中的方法进行增强

package tech.pdai.springframework.service;

import java.util.Collections;
import java.util.List;

import tech.pdai.springframework.entity.User;

/**
 * @author pdai
 */
public class UserServiceImpl {

    /**
     * find user list.
     *
     * @return user list
     */
    public List<User> findUserList() {
        return Collections.singletonList(new User("pdai", 18));
    }

    /**
     * add user
     */
    public void addUser() {
        // do something
    }

}

cglib代理

cglib代理类,需要实现MethodInterceptor接口,并指定代理目标类target

package tech.pdai.springframework.proxy;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

/**
 * This class is for proxy demo.
 *
 * @author pdai
 */
public class UserLogProxy implements MethodInterceptor {

    /**
     * 业务类对象,供代理方法中进行真正的业务方法调用
     */
    private Object target;

    public Object getUserLogProxy(Object target) {
        //给业务对象赋值
        this.target = target;
        //创建加强器,用来创建动态代理类
        Enhancer enhancer = new Enhancer();
        //为加强器指定要代理的业务类(即:为下面生成的代理类指定父类)
        enhancer.setSuperclass(this.target.getClass());
        //设置回调:对于代理类上所有方法的调用,都会调用CallBack,而Callback则需要实现intercept()方法进行拦
        enhancer.setCallback(this);
        // 创建动态代理类对象并返回
        return enhancer.create();
    }

    // 实现回调方法
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        // log - before method
        System.out.println("[before] execute method: " + method.getName());

        // call method
        Object result = proxy.invokeSuper(obj, args);

        // log - after method
        System.out.println("[after] execute method: " + method.getName() + ", return value: " + result);
        return null;
    }
}

使用代理

启动类中指定代理目标并执行。

package tech.pdai.springframework;

import tech.pdai.springframework.proxy.UserLogProxy;
import tech.pdai.springframework.service.UserServiceImpl;

/**
 * Cglib proxy demo.
 *
 * @author pdai
 */
public class ProxyDemo {

    /**
     * main interface.
     *
     * @param args args
     */
    public static void main(String[] args) {
        // proxy
        UserServiceImpl userService = (UserServiceImpl) new UserLogProxy().getUserLogProxy(new UserServiceImpl());

        // call methods
        userService.findUserList();
        userService.addUser();
    }
}

简单测试

我们启动上述类main 函数,执行的结果如下:

[before] execute method: findUserList
[after] execute method: findUserList, return value: [User{name='pdai', age=18}]
[before] execute method: addUser
[after] execute method: addUser, return value: null

Cglib代理的流程

我们把上述Demo的主要流程画出来,你便能很快理解

更多细节:

  • 在上图中,我们可以通过在Enhancer中配置更多的参数来控制代理的行为,比如如果只希望增强这个类中的一个方法(而不是所有方法),那就增加callbackFilter来对目标类中方法进行过滤;Enhancer可以有更多的参数类配置其行为,不过我们在学习上述主要的流程就够了。
  • final方法为什么不能被代理?很显然final方法没法被子类覆盖,当然不能代理了。
  • Mockito为什么不能mock静态方法?因为mockito也是基于cglib动态代理来实现的,static方法也不能被子类覆盖,所以显然不能mock。但PowerMock可以mock静态方法,因为它直接在bytecode上工作,更多可以看 Mockito单元测试 。(pdai: 通了没?是不是so easy...)

SpringAOP中Cglib代理的实现

SpringAOP封装了cglib,通过其进行动态代理的创建。

我们看下CglibAopProxy的getProxy方法

@Override
public Object getProxy() {
  return getProxy(null);
}

@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
  if (logger.isTraceEnabled()) {
    logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
  }

  try {
    Class<?> rootClass = this.advised.getTargetClass();
    Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");

    // 上面流程图中的目标类
    Class<?> proxySuperClass = rootClass;
    if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
      proxySuperClass = rootClass.getSuperclass();
      Class<?>[] additionalInterfaces = rootClass.getInterfaces();
      for (Class<?> additionalInterface : additionalInterfaces) {
        this.advised.addInterface(additionalInterface);
      }
    }

    // Validate the class, writing log messages as necessary.
    validateClassIfNecessary(proxySuperClass, classLoader);

    // 重点看这里,就是上图的enhancer,设置各种参数来构建
    Enhancer enhancer = createEnhancer();
    if (classLoader != null) {
      enhancer.setClassLoader(classLoader);
      if (classLoader instanceof SmartClassLoader &&
          ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
        enhancer.setUseCache(false);
      }
    }
    enhancer.setSuperclass(proxySuperClass);
    enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
    enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
    enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));

    // 设置callback回调接口,即方法的增强点
    Callback[] callbacks = getCallbacks(rootClass);
    Class<?>[] types = new Class<?>[callbacks.length];
    for (int x = 0; x < types.length; x++) {
      types[x] = callbacks[x].getClass();
    }
    // 上节说到的filter
    enhancer.setCallbackFilter(new ProxyCallbackFilter(
        this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
    enhancer.setCallbackTypes(types);

    // 重点:创建proxy和其实例
    return createProxyClassAndInstance(enhancer, callbacks);
  }
  catch (CodeGenerationException | IllegalArgumentException ex) {
    throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
        ": Common causes of this problem include using a final class or a non-visible class",
        ex);
  }
  catch (Throwable ex) {
    // TargetSource.getTarget() failed
    throw new AopConfigException("Unexpected AOP exception", ex);
  }
}

获取callback的方法如下,提几个理解的要点吧,具体读者在学习的时候建议把我的例子跑一下,然后打一个断点进行理解。

rootClass
advised
exposeProxy
DynamicAdvisedInterceptor
targetInterceptor
private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
  // Parameters used for optimization choices...
  boolean exposeProxy = this.advised.isExposeProxy();
  boolean isFrozen = this.advised.isFrozen();
  boolean isStatic = this.advised.getTargetSource().isStatic();

  // Choose an "aop" interceptor (used for AOP calls).
  Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);

  // Choose a "straight to target" interceptor. (used for calls that are
  // unadvised but can return this). May be required to expose the proxy.
  Callback targetInterceptor;
  if (exposeProxy) {
    targetInterceptor = (isStatic ?
        new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
        new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource()));
  }
  else {
    targetInterceptor = (isStatic ?
        new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
        new DynamicUnadvisedInterceptor(this.advised.getTargetSource()));
  }

  // Choose a "direct to target" dispatcher (used for
  // unadvised calls to static targets that cannot return this).
  Callback targetDispatcher = (isStatic ?
      new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp());

  Callback[] mainCallbacks = new Callback[] {
      aopInterceptor,  // 
      targetInterceptor,  // invoke target without considering advice, if optimized
      new SerializableNoOp(),  // no override for methods mapped to this
      targetDispatcher, this.advisedDispatcher,
      new EqualsInterceptor(this.advised),
      new HashCodeInterceptor(this.advised)
  };

  Callback[] callbacks;

  // If the target is a static one and the advice chain is frozen,
  // then we can make some optimizations by sending the AOP calls
  // direct to the target using the fixed chain for that method.
  if (isStatic && isFrozen) {
    Method[] methods = rootClass.getMethods();
    Callback[] fixedCallbacks = new Callback[methods.length];
    this.fixedInterceptorMap = CollectionUtils.newHashMap(methods.length);

    // TODO: small memory optimization here (can skip creation for methods with no advice)
    for (int x = 0; x < methods.length; x++) {
      Method method = methods[x];
      List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, rootClass);
      fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
          chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
      this.fixedInterceptorMap.put(method, x);
    }

    // Now copy both the callbacks from mainCallbacks
    // and fixedCallbacks into the callbacks array.
    callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
    System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
    System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
    this.fixedInterceptorOffset = mainCallbacks.length;
  }
  else {
    callbacks = mainCallbacks;
  }
  return callbacks;
}

可以结合调试,方便理解

示例源码

https://github.com/realpdai/tech-pdai-spring-demos

JAVA高级架构师基础功:Spring中AOP的两种代理方式:动态代理和CGLIB详解 在spring框架中使用了两种代理方式: 1.JDK自带的动态代理。 2.Spring框架自己提供的CGLIB的方式。 这两种也是Spring框架核心AOP的基础。 在详细讲解上述提到的动态代理和CGLIB前,需要明白如下内容: 代理,静态代理,动态代理。 一、概述 1、什么是代理(Java架构师交流企鹅裙*/*:1028678754 ) 代理的概念容易理解,比如:微商,简单来说微商就是替厂家卖... 阅读详情

相关推荐

Spring AOP 详解:从入门到实战

本文详细介绍了Spring AOP的核心概念与实际应用。Spring AOP通过面向切面编程解决了企业应用中的横切关注点问题,与传统OOP形成互补。文章阐述了AOP的基本术语(切面、连接点、切点等)和五种通知类型,对比了注解和XML两种配置方式。重点分析了execution切点表达式语法,并通过代码示例展示了如何实现日志、事务和安全等常见切面功能。Spring AOP基于代理实现运行时织入,相比AspectJ更轻量但功能稍有限制。

ljw714的专栏 1151

Spring AOP 实现原理详解之 CGLIB 动态代理

CGLIB 是一个强大的高性能的代码生成包。它广泛的被许多 AOP 的框架使用,例如 Spring AOP 和 dynaop,为他们提供方法的 interception(拦截)。CGLIB 包的底层是通过使用一个小而快的字节码处理框架 ASM,来转换字节码并生成新的类。除了 CGLIB 包,脚本语言例如 Groovy和 BeanShell,也是使用 ASM 来生成 Java 的字节码。当然不鼓励直接使用 ASM,因为它要求你必须对 JVM 内部结构包括 class 文件的格式和指令集都很熟悉。引入 CGLI

流华追梦的专栏 2550

惊人!Spring5 AOP 默认使用Cglib? 从现象到源码深度分析

Spring 5.x 中 AOP 默认依旧使用 JDK 动态代理。SpringBoot 2.x 开始,为了解决使用 JDK动态代理可能导致的类型转化异常而默认使用 CGLIB。在 SpringBoot 2.x 中,如果需要默认使用 JDK动态代理可以通过配置项spring.aop.proxy-target-class=false来进行修改,proxyTargetClass配置已无效。

sdujava2011 1338

Spring动态代理之cglib

什么是cglib? cglib (Code Generation Library )是一个第三方代码生成类库,运行时在内存中动态生成一个子类对象从而实现对目标对象功能的扩展。 cglib特点: JDK的动态代理有一个限制,就是使用动态代理的对象必须实现一个或多个接口。 如果想代理没有实现接口的类,就可以使用CGLIB实现。 CGLIB是一个强大的高性能的代码生成包,它可以在运行期扩展Java类与...

手写ArrayList 1042

AOP使用CGLIB实现AOP功能

Spring AOP实现方法之一:CGLIB 实现AOP功能

【技术纵览】行为识别前沿模型演进:从CNN到多模态大模型

本文全面解析了行为识别技术从CNN到多模态大模型的演进历程,重点介绍了SlowFast、TimeSformer、VideoMAE和InternVideo等SOTA模型的核心创新与应用实践。通过对比分析各代模型在Kinetics-400等数据集上的表现,揭示了自监督学习和多模态融合如何推动行为识别准确率突破85%,并探讨了工业部署中的技术选型策略与优化方向。

weixin_29169505的博客 155

Spring进阶 - Spring AOP实现原理详解之Cglib代理实现

代理模式(Proxy pattern): 为另一个对象提供一个替身或占位符以控制对这个对象的访问举个简单的例子:我(client)如果要买房(doOperation),可以找中介(proxy)买房,中介直接和卖方(target)买房。中介和卖方都实现买卖(doOperation)的操作。中介就是代理(proxy)。动态代理就是,在程序运行期,创建目标对象的代理对象,并对目标对象中的方法进行功能性增强的一种技术。在生成代理对象的过程中,目标对象不变,代理对象中的方法是目标对象方法的增强方法。

珍惜当下 889

从零开始理解异构算力调度:全国一体化算力算网平台实战解析

本文深入解析了异构算力调度技术在全国一体化算力算网平台中的实战应用。通过资源抽象层设计、动态感知引擎和跨云调度算法,实现AI训练任务的高效资源分配,显著提升计算效率并降低成本。特别针对GPU等异构算力的智能调度方案,为多云协同环境下的AI开发提供实用指南。

weixin_28730927的博客 334

Spring AOP实现原理详解(JDK和CGLib的动态代理)

在Spring中的AOP是依靠动态代理来实现切面编程的,而这两者又是有区别的。

qq_44591181的博客 1099

STM32 BootLoader 入门教程:从原理到 APP 跳转实现

在 STM32 项目开发中,BootLoader 通常用于实现固件升级、程序引导和应用程序校验。本文从最基础的 BootLoader 原理开始,讲解 STM32 内部 Flash 分区设计、APP 地址偏移、向量表重定位、BootLoader 跳转 APP 的核心代码,以及实际开发中常见的问题。本文适合刚开始接触 STM32 BootLoader、IAP 在线升级、串口升级、OTA 升级的开发者阅读。

lidecong133的博客 1678

OpenClaw安装方式那么多,但建议大家还是用云厂商吧

OpenCloud的安装方式多样,包括One-liner、npm、pnpm和Hackable等。One-liner提供高效的单行命令安装;npm和pnpm作为Node.js包管理工具,分别提供常规和高性能的安装选项;Hackable则支持定制化安装。不同系统(macOS、Windows)和终端(PowerShell、CMD)的操作步骤各有特点,用户需根据自身技术背景选择合适的安装方式。官方推荐使用闲置计算资源或云部署方案以获得更佳体验。

涛涛讲AI 1401

Spring框架系列(11) - Spring AOP实现原理详解之Cglib代理实现

我们在前文中已经介绍了SpringAOP的切面实现和创建动态代理的过程,那么动态代理是如何工作的呢?本文主要介绍Cglib动态代理的案例和SpringAOP实现的原理。

pdai的博客 539

conda环境的复制、备份操作

请确保将 source_env 替换为你要复制的现有环境的名称,并将 target_env 替换为你要创建的新环境的名称。要备份一个Conda虚拟环境,你需要将环境的配置信息和依赖包列表保存起来,以便在需要的时候能够重新创建相同的环境。要将现有的 conda 环境复制为其他环境,可以使用 conda create 命令并克隆已存在的环境。

Dollhan的博客 3774

一文读懂Spring AOP底层实现原理!

hello啊,各位观众姥爷们!!!本baby今天又来报道了!哈哈哈哈哈嗝🐶。

牛马baby的博客 787

多模态大模型:技术原理与实战 全球多模态大模型介绍

关键词:多模态大模型、深度学习、计算机视觉、自然语言处理、跨模态学习、迁移学习、人工智能随着人工智能技术的飞速发展,多模态大模型已经成为了当前AI领域最热门的研究方向之一。多模态大模型能够同时处理和理解多种类型的数据,如文本、图像、音频和视频等,这为AI系统在复杂场景下的应用提供了更加强大和灵活的能力。本文将深入探讨多模态大模型的技术原理,介绍其实战应用,并对全球主要的多模态大模型进行全面的介绍和比较。

AI天才研究院 4270

OpenWRT使用4G/5G无线网卡模块上网

将4G/5G开发板插入设备,终端输入lsusb或lspci,看设备是否识别到4G/5G模块。

1万+

【Spring】Spring AOP 实现与动态代理原理深度解析,AOP 核心实现机制,JDK 动态代理实现原理

Spring AOP 实现与动态代理原理深度解析,AOP 核心实现机制,JDK 动态代理实现原理。通过理解动态代理和拦截链机制,可高效实现日志记录、事务管理等横切关注点,提升系统可维护性。

夜雨的博客 1363

C#企业级工作流管理:从优化到重构的实战指南——代码深度解析与性能调优策略

本文通过Workflow Core与Elsa引擎实现企业审批流程优化,将处理时间从72小时缩短至2小时,效率提升200%。文章包含12个代码示例,涵盖流程梳理、引擎选型(对比Workflow Core与Elsa特性)、模块化重构(策略模式应用)及异常处理机制。关键实现包括:可视化流程建模、Serilog性能监控、Elsa集成配置、策略模式消除重复代码,以及补偿事务设计。最终方案支持高并发,通过数据库连接池优化性能,为企业级工作流系统提供完整技术方案。

墨夶的博客 896

深入浅出 AOP:织入时机、JDK 动态代理与 CGLIB 原理及 Spring 选择策略

对比维度JDK 动态代理CGLIB 动态代理核心前提被代理类必须实现至少一个接口被代理类无需实现接口,基于继承生成子类底层技术依赖包,核心是反射依赖 ASM 字节码框架,直接生成字节码调用机制首次调用走反射,后续优化为动态字节码直接调用借助FastClass,全程无反射直接调用方法支持仅支持代理接口的public方法原生支持非 private/final 方法,Spring 封装后默认仅增强 public代理对象类型接口的实现类,仅能强转为接口类型被代理类的子类,可强转为被代理类本身。

l7_yuqi的博客 976

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

深入理解 AOP 与 Spring AOP:从概念到实战的全面解析

AOP 是一种强大的编程范式,它通过将横切关注点与核心业务逻辑分离,提高了代码的可维护性和复用性。Spring AOP 作为 AOP 的具体实现框架,提供了简单易用的 API 和配置方式,让我们可以轻松实现各种 AOP 功能。通过本文的介绍,我们了解了 AOP 的核心概念、实现方式、Spring AOP 的底层原理和配置方法,以及 AOP 在实际开发中的应用案例。掌握 AOP 和 Spring AOP,将帮助我们写出更加优雅、高效的代码。

wf23671425的博客 847

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Spring AOP和代理原理--收藏

人工智能,零基础入门!http://www.captainbed.net/inner 我们知道,Spring 中 AOP 是一大核心技术,面试中也经常被问到。 一、序言 几个常见的问题 针对这一块的东西,一般下面几个问题面试官问的比较多: * Spring AOP用的是哪种设计模式? * 谈谈你对代理模式的理解? * 静态代理和动态代理有什么区别? * 如何实现动态代理? *...

code_monkey的博客 19万+

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

Spring AOP 代理模式:CGLIB 与 JDK 动态代理区别

在讲区别之前,我们先明确一个核心概念:Spring AOP 的本质是「动态代理」,简单来说,就是 Spring 会在运行时,动态生成一个「代理对象」,这个代理对象会包裹住目标对象(我们的业务对象),当我们调用目标对象的方法时,实际上是先调用代理对象的方法,代理对象在方法执行前后,插入增强逻辑(如日志、限流),最后再执行目标对象的核心业务逻辑。CGLIB 代理的核心是「面向继承」,代理对象是目标对象的「子类」,通过重写目标方法实现增强,无需目标对象实现接口,但目标方法不能是 final 修饰。

。。。 907

Spring AOP面向切面编程核心概念与实现原理

Spring AOP作为一种强大的编程范式,通过将横切关注点与业务逻辑分离,极大地提高了代码的模块化程度和可维护性。本文深入探讨了AOP的核心概念、实现原理和各种通知类型,展示了切点表达式的强大匹配能力,并通过实际应用场景说明了AOP在企业级应用中的价值。Spring AOP底层依赖JDK动态代理和CGLIB技术,通过创建目标对象的代理来实现方法拦截和增强。在实际应用中,Spring AOP广泛用于事务管理、日志记录、性能监控、安全控制等场景,大大简化了系统实现。

程序媛学姐的博客 1575

详解 Spring AOP:核心概念、实现原理与配置实践

AOP(面向切面编程):将与业务无关但被多个业务模块共同调用的共性逻辑(如日志、事务)封装为 “切面”,通过动态织入的方式融入业务流程,以减少重复代码、降低耦合度,提升可维护性与可扩展性1。切面(Aspect): “切点 + 通知” ,它是 AOP 实现的核心载体,包含了 “要增强的方法(切点)” 和 “增强的逻辑(通知)”,例如 “给用户查询方法加日志” 就是一个切面。目标对象(Target):即被代理的对象,也就是包含核心业务逻辑的对象,比如处理用户数据的类。连接点(Join Point)

2401_89052850的博客 876

全网最强剖析Spring AOP底层原理

本文深入讲解了Spring AOP的核心原理,从静态代理模式入手,通过房东出租房屋的案例形象说明代理模式的运作机制。静态代理虽然直观,但存在类文件过多、维护性差等缺点。随后重点介绍了Spring动态代理的实现方式,详细分析了开发步骤:创建原始对象、定义额外功能、定义切入点和组装切面。文章特别强调了动态代理通过字节码技术在JVM运行时创建代理类的特点,以及相比静态代理在维护性和扩展性上的优势。最后对额外功能中的MethodBeforeAdvice接口及其参数进行了详细解析。全文结合代码示例和示意图,帮助读者深

qq_45832461的博客 2500

Java 设计模式——代理模式:从静态代理到 Spring AOP 最优实现

本文探讨了Java代理模式的核心价值与实现方式。代理模式通过引入代理对象作为中间层,有效解耦业务逻辑与增强功能,解决传统写法中存在的耦合严重、代码冗余和职责混乱问题。 文章从静态代理和动态代理两个维度展开,详细介绍了三种实现方式: 静态代理:手动编写代理类,简单直观但扩展性差 JDK动态代理:基于接口运行时生成代理类,灵活性高 CGLIB动态代理:通过字节码技术代理普通类 重点分析了静态代理的实现过程,包括定义抽象接口、实现目标对象、创建代理对象等步骤,并对比了其优缺点。代理模式特别适用于需要在不修改业务代

qq_46601365的博客 1076
上一篇: Redis 过期删除策略和内存淘汰策略有什么区别?
下一篇: Kubernetes 集群和应用监控方案的设计与实践
JavaMonsterr
博客等级 码龄4年 211粉丝 481原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值