我对AOP的理解

谈谈对AOP的认识二——AOP概念术语理解 一、AOP的术语         上篇博客介绍了AOP的由来,及使用aop的便利,在深入了解aop之前,我们当然得先了解一下其众多的概念性术语:         1、 切面(Aspect)     一个关注点的模块化,这个关注点可能会横切多个对象。事务管理是J2EE应用中一个关于横切关注点的很好的例子。在Spring AOP中,切面可以使用基于模式或者基于@Aspe 阅读详情

 

1、问题 


问题:想要添加日志记录、性能监控、安全监测 

 

2、最初解决方案 

2.1、最初解决方案

缺点:太多重复代码,且紧耦合

 

2.2、抽象类进行共性设计,子类进行个性设计,此处不讲解,缺点一荣俱荣,一损俱损

 

2.3、使用装饰器模式/代理模式改进的解决方案

装饰器模式:动态地给一个对象添加一些额外的职责。就增加功能来说, 装饰器模式相比生成子类更为灵活。
代理模式:为其他对象提供一种代理以控制对这个对象的访问。


 
缺点:紧耦合,每个业务逻辑需要一个装饰器实现或代理
 
2.4、JDK动态代理解决方案(比较通用的解决方案) 
Java代码   收藏代码
  1. public class MyInvocationHandler implements InvocationHandler {   
  2.     private Object target;  
  3.     public MyInvocationHandler(Object target) {  
  4.         this.target = target;  
  5.     }  
  6.     @Override  
  7.     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {  
  8.         //1.记录日志    2.时间统计开始      3.安全检查  
  9.         Object retVal = method.invoke(target, args);  
  10.         //4.时间统计结束  
  11.         return retVal;     
  12.     }  
  13.     public static Object proxy(Object target) {  
  14.         return Proxy.newProxyInstance(target.getClass().getClassLoader(),   
  15.                 target.getClass().getInterfaces(), new MyInvocationHandler(target));  
  16.     }  
  17. }  

 编程模型 

Java代码   收藏代码
  1.   //proxy     在其上调用方法的代理实例   
  2.   //method 拦截的方法  
  3.   //args       拦截的参数  
  4.   Override  
  5.    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {  
  6.        Object retVal=null;  
  7.        //预处理  
  8.        //前置条件判断  
  9.        boolean ok = true;          
  10.        if(!ok) {//不满足条件  
  11.            throw new RuntimeException("你没有权限");  
  12.        }  
  13.        else {//反射调用目标对象的某个方法  
  14.            retVal = method.invoke(target, args);  
  15.        }  
  16.        //后处理  
  17.        return retVal;  
  18.    }  
  19.    

缺点:使用麻烦,不能代理类,只能代理接口  

 

CGLIB动态代理解决方案(比较通用的解决方案)
Java代码   收藏代码
  1. public class MyInterceptor implements MethodInterceptor  {    
  2.     private Object target;  
  3.     public MyInterceptor(Object target) {  
  4.         this.target = target;  
  5.     }  
  6.     @Override  
  7.     public Object intercept(Object proxy, Method method, Object[] args,   
  8.                                          MethodProxy invocation) throws Throwable {  
  9.         //1.记录日志 2.时间统计开始   3.安全检查  
  10.         Object retVal = invocation.invoke(target, args);  
  11.         //4.时间统计结束  
  12.         return retVal;     
  13.     }  
  14.     public static Object proxy(Object target) {  
  15.         return Enhancer.create(target.getClass(), new MyInterceptor(target));  
  16.     }  
  17. }  

 编程模型

Java代码   收藏代码
  1.  //proxy 在其上调用方法的代理实例    method拦截的方法    args  拦截的参数  
  2.  //invocation 用来去调用被代理对象方法的  
  3. @Override  
  4. public Object intercept(Object proxy, Method method, Object[] args,   
  5.                                        MethodProxy invocation) throws Throwable {  
  6.     //预处理  
  7.     //前置条件判断  
  8.     boolean ok = true;          
  9.     if(!ok) {//不满足条件  
  10.         throw new RuntimeException("出错了");  
  11.     }  
  12.     else {//调用目标对象的某个方法  
  13.         Object retVal = invocation.invoke(target, args);  
  14.     }  
  15.     //后处理  
  16.     return retVal;  
  17. }  
优点:能代理接口和类
缺点:使用麻烦,不能代理final类

 

动态代理本质 

本质:对目标对象增强
           最终表现为类(动态创建子类),看手工生成(子类)还是自动生成(子类)
代理限制:
           只能在父类方法被调用之前或之后进行增强(功能的修改),不能在中间进行修改,要想在方法调用中增强,需要ASM(java 字节码生成库)
其他动态代理框架
jboss:javassist (hibernate 3.3中默认为javassist)
                           (hibernate 3.3之前中默认为cglib)

 


 
2.5、AOP解决方案(通用且简单的解决方案)
Java代码   收藏代码
  1. @Aspect  
  2. public class PayEbiAspect {      
  3.     @Pointcut(value="execution(* pay(..))")  
  4.     public void pointcut() {}  
  5.     @Around(value="pointcut()")  
  6.     public Object around(ProceedingJoinPoint pjp) throws Throwable {  
  7.         //1.记录日志  
  8.         //2.时间统计开始  
  9.         //3.安全检查  
  10.         Object retVal = pjp.proceed();//调用目标对象的真正方法  
  11.         //4.时间统计结束  
  12.         return retVal;  
  13.     }  
  14. }  
编程模型
Java代码   收藏代码
  1. //2 切入点  
  2. @Pointcut(value="execution(* *(..))")  
  3. public void pointcut() {}  
  4. //3 拦截器的interceptor  
  5. @Around(value="pointcut()")  
  6. public Object around(ProceedingJoinPoint pjp) throws Throwable {  
  7.     Object retVal=null;  
  8.     //预处理  
  9.     //前置条件判断  
  10.     boolean ok = true;  
  11.     if(!ok) {//不满足条件  
  12.        throw new RuntimeException("你没有权限");  
  13.     }  
  14.     else {//调用目标对象的某个方法  
  15.          retVal = pjp.proceed();   
  16.     }  
  17.     //后处理  
  18.     return retVal;  
  19. }  
 
缺点:依赖AOP框架 
 
AOP入门
概念:
 
n 关注点:可以认为是所关注的任何东西,比如上边的支付组件;
n 关注点分离:将问题细化为单独部分,即可以理解为不可再分割的组件,如上边的日志组件和支付组件;
n 横切关注点:会在多个模块中出现,使用现有的编程方法,横切关注点会横越多个模块,结果是使系统难以设计、理解、实现和演进,如日志组件横切于支付组件。
 
织入:横切关注点分离后,需要通过某种技术将横切关注点融合到系统中从而完成需要的功能,因此需要织入,织入可能在编译期、加载期、运行期等进行。
 
nAOP是什么(Aspect   Oriented   Programming)
 AOP是一种编程范式,提供从另一个角度来考虑程序结构以完善面向对象编程(OOP)。
 AOP为开发者提供了一种描述横切关注点的机制,并能够自动将横切关注点织入到面向对象的软件系统中,从而实现了横切关注点的模块化。
 AOP能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任,例如事务处理、日志管理、权限控制等,封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。
nAOP能干什么,也是AOP带来的好处
1:降低模块的耦合度
2:使系统容易扩展
3:设计决定的迟绑定:使用AOP,设计师可以推迟为将来的需求作决定,因为它
可以把这种需求作为独立的方面很容易的实现。
4:更好的代码复用性

 
AOP基本概念
 连接点(Joinpoint):
    表示需要在程序中插入横切关注点的扩展点,连接点可能是类初始化、方法执行、方法调用、字段调用或处理异常等等,Spring只支持方法执行连接点, 在AOP中表示为“在哪里做”;
切入点(Pointcut):
    选择一组相关连接点的模式,即可以认为连接点的集合,Spring支持perl5正则表达式和AspectJ切入点模式,Spring默认使用AspectJ语法, 在AOP中表示为“在哪里做的集合”;
增强(Advice):或称为增强
    在连接点上执行的行为,增强提供了在AOP中需要在切入点所选择的连接点处进行扩展现有行为的手段;包括前置增强(before advice)、后置增强 (after advice)、环绕增强 (around advice),在Spring中通过代理模式实现AOP,并通过拦截器模式以环绕连接点的拦截器链织入增强 ; 在AOP中表示为“做什么”;
方面/切面(Aspect):
      横切关注点的模块化,比如上边提到的日志组件。可以认为是增强、引入和切入点的组合;在Spring中可以使用Schema和@AspectJ方式进行组织实现; 在AOP中表示为“在哪里做和做什么集合”;
目标对象(Target Object):
    需要被织入横切关注点的对象,即该对象是切入点选择的对象,需要被增强的对象,从而也可称为“被增强对象”;由于Spring AOP 通过代理模式实现,从而这个对象永远是被代理对象, 在AOP中表示为“对谁做”;
AOP代理(AOP Proxy):
    AOP框架使用代理模式创建的对象,从而实现在连接点处插入增强(即应用切面),就是 通过代理来对目标对象应用切面。在Spring中,AOP代理可以用JDK动态代理或CGLIB代理实现,而通过拦截器模型应用切面。
织入(Weaving):
    织入是一个过程,是将切面应用到目标对象从而创建出AOP代理对象的过程,织入可以在编译期、类装载期、运行期进行。
引入(inter-type declaration):
    也称为内部类型声明,为已有的类添加额外新的字段或方法,Spring允许引入新的接口(必须对应一个实现)到所有被代理对象(目标对象),  在AOP中表示为“做什么(新增什么)”;
 
AOP的Advice类型
前置增强(Before advice):
    在某连接点之前执行的增强,但这个增强不能阻止连接点前的执行(除非它抛出一个异常)。
后置返回增强(After returning advice):
    在某连接点正常完成后执行的增强:例如,一个方法没有抛出任何异常,正常返回。
后置异常增强(After throwing advice):
    在方法抛出异常退出时执行的增强。
后置最终增强(After (finally) advice):
    当某连接点退出的时候执行的增强(不论是正常返回还是异常退出)。
环绕增强(Around Advice):
    包围一个连接点的增强,如方法调用。这是最强大的一种增强类型。 环绕增强可以在方法调用前后完成自定义的行为。它也会选择是否继续执行连接点或直接返回它们自己的返回值或抛出异常来结束执行。


 
AOP开发步骤
 
 
  类似于IoC/DI容器开发步骤,需要描述哪个连接点需要哪个通用功能(增强 )
 
 
 
横切关注点的表现有:  
  ·代码纠结/混乱——
当一个模块或代码段同时管理多个关注点时发生这种情况。如我既要实现业务、还要实现安全和事务。即有些关注点同时被多个不同的模块实现。实现了重复的功能。
   ·代码分散——当一个关注点分布在许多模块中并且未能很好地局部化和模块化时发生这种情况 。如许多模块调用用户是否登录验证代码。调用了重复的功能。
 
 
 
AOP包括三个清晰的开发步骤:
1: 功能横切:找出横切关注点。
2: 实现分离:各自独立的实现这些横切关注点所需要完成的功能。
3: 功能回贴:在这一步里,方面集成器通过创建一个模块单元—— 方面来指定重组的规则。重组过程 ——也叫织入或结合 —— 则使用这些信息来构建最终系统。
 
推荐阅读书籍:
AspectJ in Action

AOSD中文版--基于用例的面向方面软件开发

面试官:谈谈你对IOC和AOP的理解及AOP四种实现方式 IOC控制反转(IOC)是一种设计思想,就是将原本在程序中需要手动创建对象,现在交由Spring管理创建。举个例子,原本我们要在A类中调用B类的方法,就要直接在A中new出B类对象,然后调用B类中的方法,虽然能实现效果,不过存在一个问题,更改需求会对源代码进行修改,这是大忌。现在创建B对象就交给了Spring,在Spring中,B类对象被看成Bean对象(Spring中类就是Bean),这个Bean对象由spring容器进行创建和管理,当我们在配置文件中配置下的AOP。... 阅读详情

相关推荐

STM32F407硬件IIC驱动OLED避坑实录:从‘不显示’到‘稳定刷屏’的完整调试过程

本文详细记录了使用STM32F407硬件IIC驱动OLED屏幕的完整调试过程,从初始的‘不显示’问题到最终实现‘稳定刷屏’。文章涵盖了硬件接线、I2C外设配置、常见问题排查及性能优化技巧,特别针对STM32标准库开发中的难点提供了实用解决方案,是嵌入式开发者驱动OLED屏幕的实用指南。

weixin_30315723的博客 303

谈谈你对AOP的理解

概念: AOP (面向切面编程):即面向规则编程,找出多个类中有一定规律的代码,开发时拆开,运行时再合并。本质:解耦,专人做专事。 应用场景: 1、用于日志打印 2、用于全局异常处理拦截 3、返回值统一处理 4、多数据源切换 AOP底层实现原理是动态代理。 spring默认使用jdk动态代理,如果没有实现接口,就使用cglib代理; JDK动态代理:利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。 流程: 1、通过实现 Invocatio

m0_37840000的博客 3191

可信数据空间:可信空间、区域功能节点、业务功能节点、连接器的关联关系

可信数据空间通过分层架构实现安全数据共享:可信空间作为顶层制定全局规则;区域功能节点协调辖区内功能节点协作;功能节点提供具体数据服务;连接器作为唯一通信通道确保安全交互。系统采用"规则自上而下约束,数据自下而上流动"机制,通过分层治理和标准化连接,在保证数据主权的同时实现跨域协作,具有策略分级执行、去中心化治理等特性,支持灵活扩展业务场景。

友莘居士的博客 1686

浅谈对AOP的理解,简单易懂

简单了过了一边,能帮助人迅速理解

qq_42176665的博客 1435

UniApp X 网络请求避坑指南:从 JS 到 UTS 的 JSON 数据处理全解析

摘要:UniAppX开发中处理JSON数据时,UTS强类型特性要求开发者改变JS习惯。本文对比两种主流方案:1)UTSJSONObject通过keypath访问数据,兼容JS但缺乏类型提示;2)type+泛型方案,通过定义数据类型实现强类型校验和智能提示,推荐用于固定数据结构。文章详细演示了两种方式的具体实现、转换方法及实战案例,并提供了类型定义技巧和注意事项,帮助开发者编写更稳定高效的跨平台应用。

归梦工作室 2790

Visual Studio 6.0 镜像下载全指南:从企业版到中文版

本文提供Visual Studio 6.0企业版和中文版的镜像下载全指南,包括详细版本解析、已验证的下载链接及校验信息。针对现代系统的安装技巧和兼容性处理方案,帮助开发者高效获取并运行这一经典开发工具,特别适合维护遗留系统的专业人员。

weixin_33712987的博客 1019

AOP介绍和使用

⽽ AOP 是⼀种思想,⽽ Spring AOP 是⼀个框架,提供了⼀种对 AOP 思想的实现,它们的关系和 IoC 与 DI 类似。@Slf4j@Component@Aspect//定义切点//定义通知//这里注意,环绕式通知必须自己写返回结果log.info("之前");try{//调用目标方法log.info("之后");return oj;@Aspect是aop框架中提供的,表示是一个切面。

薛定谔的猫的博客 8843

Arduino与Proteus仿真实例-HG7881(L9110)驱动直流电机仿真

HG7881(L9110)驱动直流电机仿真 HG7881 (L9110) 双通道电机驱动器模块。 HG7881 (L9110) 是一款紧凑型电机驱动芯片,支持 2.5-12V 电压范围,800mA 连续电流。 这些芯片具有内置输出钳位二极管以保护敏感的微控制器电子设备。 它们适用于非常小的机器人项目。 每个 HG7881 (L9110) 芯片都能够使用两个数字控制输入驱动单个直流电机。 一个输入用于选择电机方向,而另一个用于控制电机速度。 速度是通过使用 PWM 脉冲宽度调制来控制的。 电机驱动器通常具有

视觉与物联智能 3050

AOP的缺点

虽然AOP具有一些缺点,但在许多场景下,它仍然是一个有用的工具,特别是对于处理横切关注点的复杂问题时。合理地使用AOP并结合良好的代码组织和文档,可以最大限度地发挥其优点,同时尽量避免其缺点。

qq_46130027的博客 818

可控异常的契约化设计:在 ABAP 中用 CX_STATIC_CHECK 把可预期错误变成接口的一部分

文章摘要: 本文探讨了ABAP系统中异常处理的工程化设计原则,强调将可预期的业务异常作为接口契约的一部分。核心观点是:对于调用方能够合理处理的错误情况,应使用继承自CX_STATIC_CHECK的受检异常,通过方法签名强制调用方处理或显式转发。文章对比了ABAP三大异常根类的适用场景,提出"三问法"判断异常是否适合受检处理,并给出了包含上下文信息的异常类实现示例。通过Fiori文件上传案例,展示了如何在分层架构中合理传递和转换异常,最终在OData服务层将业务异常映射为标准错误响应。这种

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 3064

SAP_SD模块深度解析SAP信用检查中的“未清数量”取值逻辑

确认数量 vs 订单数量:如果系统配置了可用性检查(ATP),并且订单只确认了部分数量,信用检查通常只占用已确认数量的额度(具体取决于信用组的配置)。在SAP中,未清订单数量的计算并非简单读取订单行项目的目标数量(VBAK-KWMENG),而是基于**计划行(Schedule Lines)**层级来汇总的。状态的转换点:当交货单创建(VL01N)并保存时,这部分数量对应订单的“未清订单数量”减少,“未清交货数量”增加。业务人员眼中的未清数量很简单:“我卖了100个,发了30个,未清就是70个”。

我小时候很黑的博客 313

SpringAOP(图文详解)

Spring实现的AOP是代理模式,给调用者使用的实际是已经过加工的对象,你编程时方法体里只写了A,但调用者拿到的对象的方法体却是xAy。x和y总还是需要你来写的,这就是增强。x和y具体在什么时候被调用总还是需要你来规定的,虽然是基于约定的声明这种简单的规定,这就是切点。

lhj520cb的博客 5万+

OpenHarmony AI系列:神经网络处理单元(NPU)驱动架构与实现详解

NPU(Neural Processing Unit,神经网络处理单元)是专门为神经网络计算设计的硬件加速器。在OpenHarmony系统中,NPU驱动是通过NNRT(Neural Network Runtime,神经网络运行时)框架实现的,它作为中间桥梁连接上层AI推理框架和底层NPU硬件,实现AI模型的跨芯片推理计算。

m0_67505153的博客 665

对AOP的理解

1 AOP面向切面编程基于IoC,是对OOP的有益补充;AOP代表的是一个横向的关系,剖解开封装的对象内部,并将那些影响了 多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即切面。简单地说,就是将那些与业务无关,却为业务模块所共同调用的 逻辑或责任封装起来,比如日志记录,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。 2 Spring实现AOP:J...

weixin_44227923的博客 4022

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

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

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

Spring AOP的实现——对AOP的理解

什么是AOP AOP(Aspect Orient Programming,即面向切面编程)。AOP和OOP(Object Orient Programming,面向对象编程)互为补充,面向对象编程将程序分解成各个层次的对象,而面向切面编程将程序运行过程分解成各个切面。可以这么理解:面向对象编程是从静态的角度考虑程序结构,而面向切面编程是从动态的角度考虑程序的运行。 为什么要用AOP

点滴积累 4046

精雕软件(JDpaint) 5.5 绿色版

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

Spring AOP理解

Spring AOP基础解读

I_m_j的博客 1732

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

说说个人对AOP的理解

AOP做java开发的同学都很熟悉,这是怎样的一个概念,即便用了很久,但在回答对AOP的理解此类问题时,回答的还是不够全面,所以特地做此总结。本篇只做理解,暂不谈论原理。 AOP(Aspect Oriented Programming ) 面向切面编程,也是Spring框架的核心之一,它是一种先进的思想,为解耦而生,作为这种思想的技术支撑离不开动态代理(下篇会进行详细讨论)。可以说是OOP(Ob...

LiHuaxin_BJ的博客 2737

理解AOP

这篇博客讲的比较通俗易懂,适合新手入门:轻松理解AOP。

瞬息之间 329

AOP的理解

AOP的理解

weixin_41563161的博客 195

aop阻止方法运行_aop简单理解

一、对AOP的初印象首先先给出一段比较专业的术语(来自百度):在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方 式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个 热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑 的各个部分进行隔离,从而使得业务...

weixin_42440389的博客 714

初学AOP的一些理解

关于AOP的一些理解 (一)从TestSpring开始说起: 先获取核心业务ProductService的bean创建一个ProductService对象,调用业务中的doSomeService方法,此时可以理解为就在这个方法调用时,发生了中断; (二)接着,讲applicationContext.xml这个文件: ①在aop的config里面第一段的意思是声明了一个切入点(pointcut),这个切入点的id为“loggerCutpoint”; expression属性指定切入点表达式,"* com.h

weixin_44614828的博客 948

原来理解 AOP 可以这么简单

以常见的生活场景:居民用水为例,通俗易懂的理解AOP,一看就会。

杨幂等 482

说说你对AOP的理解

特性JDK动态代理CGLIB动态代理实现基础目标类的接口目标类的子类继承依赖需实现至少一个接口无依赖(可代理任意类)性能调用时反射开销较大生成代理慢,但调用效率高增强限制只能拦截接口方法可拦截所有非final方法AOP 的本质是通过动态代理在运行时“包装”目标对象JDK代理利用接口实现代理,通过插入横切逻辑;CGLIB代理通过继承重写方法,由MethodInterceptor控制增强流程。

tschen的博客 747

通俗理解Spring的IOC和AOP

字面意思通俗理解: 参考Aop理解地址:https://blog.youkuaiyun.com/ios_xumin/article/details/78465782 参考IOC和DI理解地址:https://blog.youkuaiyun.com/lhy55040817/article/details/5335699 具体代码理解:https://www.cnblogs.com/vanl/p/5607534....

有的话没说出来之前,你是他的主人,一旦说出来你就成了他的奴隶||想要干好事,别太把自己当人,别把别人太不当人||认识这个人就是开了一扇窗户,就能看到不一样的东西,听到不一样的声音,能让你思考、觉悟,这已经够了 601

Spring AOP的理解

根据https://blog.youkuaiyun.com/qukaiwei/article/details/50367761 做了一张图,便于自己更好的理解AOP的概念。

zhanjunpeng01的博客 283

对spring aop的理解

今天面试的时候,被问到对aop的理解,正好前几天有看到这个问题,凭着印象回答了下 我:aop用到了动态代理 面试官:动态代理有哪几种,原理是什么 我:动态代理有两种,一种是JDK自带的,一种是cglib 面试官:他们有什么区别 我:JDK自带的动态代理是基于反射实现的,cglib是基于字节码实现的 面试官:还有什么区别 我:我就了解到这了 下面跟大家来详细解释下aop AO...

可惜没如果的博客 852
上一篇: 理解AOP
下一篇: Spring AOP 详解
鹿晗的晗
博客等级 码龄16年 22粉丝 23原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值