Spring AOP中的动态代理机制

Spring AOP的两种动态代理方式的原理和实现(JDK和CGLIB) 代理机制 Spring 的AOP 部分使用使用JDK动态代理,部分使用CGLIB来为目标对象创建代理。如果被代理的目标对象实现了至少一个接口,则会使用JDK动态代理;如果目标对象没有实现任何接口,则会创建CGLIB动态代理。CGLIB是第三方包,从Spring4.3开始就无需再次导入包了。 注意 客户端直接调用与目标类相对应的代理类的功能,为了保证代理类与目标类具有相同功能,代理类与目标类必须实现相同的接口 代理是实现AOP的核心和关键技术。只要是AOP,就一定会涉及代理技术 . 代理技术的分类 按照是否 阅读详情

AOP:面向切面、面向方面、面向接口是一种横切技术
横切技术运用:
1.事务管理: (1)数据库事务:(2)编程事务(3)声明事物:Spring AOP-->声明事物   
2.日志处理:
3.安全验证: Spring AOP---OOP升级  
  

静态代理原理:目标对象:调用业务逻辑    代理对象:日志管理
表示层调用--->代理对象(日志管理)-->调用目标对象

动态代理原理:spring AOP采用动态代理来实现
(1)实现InvocationHandler接口

(2)创建代理类(通过java API)

Proxy.newProxyInstance(动态加载代理类,代理类实现接口,使用handler);

(3)调用invoke方法(虚拟机自动调用方法)

日志处理
 //调用目标对象
 method.invoke("目标对象","参数");
 日志处理

通过代理对象--(请求信息)-->目标对象---(返回信息)----> 代理对象

 

Spring 动态代理中的基本概念

1、关注点(concern)
   一个关注点可以是一个特定的问题,概念、或者应用程序的兴趣点。总而言之,应用程序必须达到一个目标
   安全验证、日志记录、事务管理都是一个关注点
   在oo应用程序中,关注点可能已经被代码模块化了还可能散落在整个对象模型中
2、横切关注点(crosscutting concern)
   如何一个关注点的实现代码散落在多个类中或方法中
3、方面(aspect)
   一个方面是对一个横切关注点模块化,它将那些原本散落在各处的,
   用于实现这个关注点的代码规整在一处
4、建议(advice)通知
   advice是point cut执行代码,是方面执行的具体实现
5、切入点(pointcut)
   用于指定某个建议用到何处
6、织入(weaving)
   将aspect(方面)运用到目标对象的过程
7、连接点(join point)
  程序执行过程中的一个点 

通知类型:
  try{
    //前置通知
         //环绕通知
            //调用目标对象方法
         //环绕通知
    //后置通知
  }catch(){
    //异常通知
  }finally{
    //终止通知
  }

 

流程图

 

一.静态代理原理实例:

项目结构图:                                                                    

IUserServ接口代码

public interface IUserServ {
	List<User> findAllUser();
	int deleteUserById(User user);
	int saveUser(User user);
}


UserServImpl实现类代码

public class UserServImpl implements IUserServ {
	public int deleteUserById(User user) {
		System.out.println("******执行删除方法******");
		return 0;
	}
	public List<User> findAllUser() {
		System.out.println("*******执行查询方法*******");
		return null;
	}
	public int saveUser(User user) {
		System.out.println("*******执行添加方法********");
		return 0;
	}
}

UserServProxyImpl实现类代码

//代理类:完成日志输出
public class UserServProxyImpl implements IUserServ {
	// 访问目标对象(UserServImpl)
	// 代理对象(UserServProxyImpl)
	// 创建目标对象
	private IUserServ iuserServ ;//= new UserServImpl();

	public UserServProxyImpl(IUserServ iuserServ){
		this.iuserServ = iuserServ;
	}
	public int deleteUserById(User user) {
		beforeLog();
        //调用目标对象里方法
		iuserServ.deleteUserById(user);
		afterLog();
		return 0;
	}

	public List<User> findAllUser() {
		beforeLog();
		//调用目标对象里方法
		iuserServ.findAllUser();
		afterLog();
		return null;
	}

	public int saveUser(User user) {
		beforeLog();
		//调用目标对象里方法
		iuserServ.saveUser(user);
		afterLog();
		return 0;
	}

	private void beforeLog() {
		System.out.println("开始执行");
	}
	
	private void afterLog() {
		System.out.println("执行完毕");
	}
}

ActionTest测试类代码

public class ActionTest {
	public static void main(String[] args) {
		//用户访问代理对象---信息->目标对象
		IUserServ iuserServ = new UserServProxyImpl(new UserServImpl());
		iuserServ.findAllUser();
	}
}

运行结果:

开始执行
*******执行查询方法*******
执行完毕
二.动态代理实例

项目结构图:

IUserServ接口代码与UserServImpl实现类代码和上述代码相同

LogHandler类代码

public class LogHandler implements InvocationHandler {
	//目标对象
	private Object targetObject;
	/**
	 * 创建动态代理类
	 * @return object(代理类)
	 */
	public Object createProxy(Object targetObject){
		this.targetObject = targetObject;
		return Proxy.newProxyInstance(
				targetObject.getClass().getClassLoader(), 
					targetObject.getClass().getInterfaces(), this);
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		Object obj = null;
		try {
			beforeLog();
			//obj: 目标对象--->代理对象的返回值--->返回给调用者的信息
			//this.invoke("目标对象","代理对象给目标对象传递参数");
			//调用目标对象中方法
			obj = method.invoke(targetObject, args);
			afterLog();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return obj;
	}
	
	//日志管理方法
	private void beforeLog(){
		System.out.println("开始执行");
	}
	
	private void afterLog(){
		System.out.println("执行完毕");
	}

}

ActionTest测试类代码:

public class ActionTest {
	public static void main(String[] args) {
		//创建代理对象iuserServ
		LogHandler handler = new LogHandler();
		IUserServ iuserServ = (IUserServ)handler.createProxy(new UserServImpl());
		iuserServ.deleteUserById(new User());
	}
}

运行结果:
开始执行
******执行删除方法******
执行完毕
三.Spring AOP使用(2.x版本之前)

项目结构图:



IUserServ接口代码与UserServImpl实现类代码和上述代码相同

配置步骤:

1、配置目标对象(applicationContext.xml)

<bean id="userServTarget" class="com.tarena.biz.impl.UserServImpl"/> 

 2、配置通知
(a)前置通知(BeforeLogAdvice)

public class BeforeLogAdvice implements MethodBeforeAdvice {
	 /**
	    * Method method:调用目标对象的方法
	    * Object[] args:发送给目标对象的参数列表
	    * Object target:目标对象
	    */
	public void before(Method method, Object[] args, Object target)
			throws Throwable {
		beforeLog();
	}
	private void beforeLog(){
		System.out.println("开始执行");
	}
}


(b)后置通知(AfterLogAdvice)

public class AfterLogAdvice implements AfterReturningAdvice {
	  /**
	    * Object returnValue:目标对象返回值
	    *  Method method:目标对象方法名
	    *  Object[] args:目标对象参数列表
	    *  Object target:目标对象
	    */
	public void afterReturning(Object returnValue, Method method,
			Object[] args, Object target) throws Throwable {
		afterLog();
	}
	private void afterLog(){
		System.out.println("执行完毕");
	}
}

       

(c)在spring容器中,让容器管理通知(applicationContext.xml)

<!-- 定义通知 -->
		<!-- 前置通知 -->
		<bean id="beforeLogAdvice" class="com.tarena.advice.BeforeLogAdvice"/>
		<!-- 后置通知 -->
		<bean id="afterLogAdvice" class="com.tarena.advice.AfterLogAdvice"/>


3、配置代理对象(applicationContext.xml)  

<!-- 代理类作用: 生成代理类,织入通知 -->  
  <bean id="userServProxy" 
   class="org.springframework.aop.framework.ProxyFactoryBean">
   <property name="interfaces">
   <!-- 可以添加多个接口 -->
    <list>
     <value>com.tarena.biz.IUserServ</value>
    </list>
   </property>
   <!-- 引入通知 -->
   <property name="interceptorNames">
    <list>
     <value>beforeLogAdvice</value>
     <value>afterLogAdvice</value>
    </list>
   </property>
   <!-- 目标对象 -->
   <property name="target" ref="userServTarget"/>
  </bean>


 4.访问()
Spring容器:通过代理对象调用-->织入通知--->目标对象
程序员:访问代理对象   

测试类(ActionTest):

public class ActionTest {
	public static void main(String[] args) {
		ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
		IUserServ iuserServ = (IUserServ)ac.getBean("userServProxy");
		iuserServ.deleteUserById(new User());
		iuserServ.findAllUser();
	}
}

运行结果:

开始执行
******执行删除方法******
执行完毕
开始执行
*******执行查询方法*******
执行完毕
四.Spring AOP使用(2.x版本之后)这种方式需要额外添加两个jar包,

存放位置在spring-framework-2.5.6.SEC01\lib\aspectj文件夹下。

项目结构图


IUserServ接口代码与UserServImpl实现类代码和上述代码相同

LogAdvice中

public class LogAdvice {
	public void beforeLog(){
		System.out.println("开始执行");
	}
	public void afterLog(){
		System.out.println("执行完毕");
	}
}

applicationContext.xml中

<!-- spring2.x后 -->
	<!-- 目标对象 -->
	<bean id="userServImpl" class="com.tarena.biz.impl.UserServImpl"/>
	<!-- 通知 -->
	<bean id="logAdvice" class="com.tarena.advice.LogAdvice"/>
	
	<aop:config>
		<aop:aspect id="logAspect" ref="logAdvice">
			<!-- 切入点 -->
			<aop:pointcut id="beforePointCut" 
	    expression="execution(* saveUser*(..))"/>
	    <aop:pointcut id="afterPointCut" 
	    expression="execution(* saveUser*(..))"/>
			
			<!-- 织入(通知作用于切入点) -->
			<aop:before method="beforeLog" pointcut-ref="beforePointCut"/>
			<aop:after method="afterLog" pointcut-ref="afterPointCut"/>
		</aop:aspect>
	</aop:config>

测试类:

public class ActionTest {
	public static void main(String[] args) {
		ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
		IUserServ iuserServ = (IUserServ)ac.getBean("userServImpl");
		iuserServ.deleteUserById(new User());
		iuserServ.findAllUser();
		iuserServ.saveUser(new User());
	}
}

运行结果
******执行删除方法******
*******执行查询方法*******
开始执行
*******执行添加方法********
执行完毕

注:如果要在业务层所有的方法前后添加日志文件,则需要更改为以下配置

<aop:pointcut id="beforePointCut" 
	    expression="execution(* com.tarena.biz.*.*(..))"/>
	    <aop:pointcut id="afterPointCut" 
	    expression="execution(* com.tarena.biz.*.*(..))"/>


运行结果:

开始执行
******执行删除方法******
执行完毕
开始执行
*******执行查询方法*******
执行完毕
开始执行
*******执行添加方法********
执行完毕


文章转自:Spring AOP动态代理原理与实现方式

从零到一:RV1126与IMX415的硬件交响曲——深入解析Linux IPC摄像头的硬件调试艺术 本文深入解析了RV1126与IMX415组合的Linux IPC摄像头硬件调试技术,涵盖硬件接口检查、设备树配置、驱动加载验证及ISP调优等关键步骤。通过详细的操作指南和常见问题解决方案,帮助开发者快速掌握摄像头调试技巧,提升开发效率。 阅读详情

相关推荐

工程伦理-知识点汇总

工程伦理-知识点汇总

m0_46091747的博客 1万+

Spring Aop 自动创建代理

Spring Aop 自动创建代理 1 BeanNameAutoProxyCreator 根据Bean名称自动创建代理 2 DefaultAdvisorAutoProxyCreator 根据Advisor本身包含信息创建代理 3 AnnotationAwareAspectJAutoProxyCreator 基于Bean中的AspectJ注解进行自动代理 1 根据Bean名称自动创建代理(),举例,对所有以DAO结尾Bean所有方法使用代理 <!--配置目标类--> <bean

顾曲周郞的博客 370

carsim与simulink联合仿真学习笔记(二)——使用C-class车模做driver model仿真(5 driver sensors)

Driver model 在carsim的Simulink库中自带外部驾驶员模型,打开后如图所示: 然后打开carsim中对应的数据集,如图所示: 具体仿真步骤不在赘述,注意到这里选择的是E-Class车模,那么如果我想选择C-Class车型进行仿真呢?点三角选择车型可以看到: 马赛克部分是我后来建的,如过没有使用过是没有马赛克部分的。那么既然这里没有C-class,又该怎么办呢? 创建C-...

xufuqiang2017的博客 4116

面向切面编程 Aop 学习笔记

大功传人,在续辉煌.......双大功三连,哈哈,加油

山河已无恙 1079

手把手教会你用yolov8从环境配置到检测任务实战

做本文章前,我浏览过很多网上资料,我发现他们总是写的含糊不清,而且实际操作起来就会有各种各样的问题,要么就是根本不适合一些小白,所以我在这里写一篇完全针对小白的yolo从入门到实战。看完本文章后大家都可以实现下图效果,数字识别是一种比较简单的检测任务,其他识别任务学完本例也能够一通百通,大家边做边学,更好的体会yolo的神奇之处。

KevenDuan的博客 2871

【UE5+Quest3】手部模型替换---3-0

这次手部模型替换遇到了一些小问题,不过好在是bug一个个都处理掉了,我会分开几个章节去整理。详细的视频教程可以参考油管大佬的视频手部素材放到文章末尾,自行下载使用。(仅用作学习研究,不可用于商用)

qbbmnnnnnn的博客 944

Spring AOP 动态代理机制

Spring AOP的动态代理有两种:一是JDK的动态代理;另一个是cglib动态代理(通过修改字节码来实现代理)。今天主要讨论JDK动态代理的方式。JDK的代理方式主要就是通过反射跟动态编译来实现的,主要实现InvocationHandler接口和生成Proxy对象。

qq_35181209的博客 1611

使用同一个时钟源clki,做两个二分频时钟,得到div2_clk1和div2_clk2,这两个时钟都能跟源时钟clki同步,但是div2_clk1和div2_clk2的相位可能是相同的,也可能是反相

比如,触发器1的初始Q为0,而触发器2的初始Q为1(这可能由于芯片制造工艺的微小差异、上电过程的随机性、或没有全局复位信号导致)。这句话的意思是:虽然div2_clk1和div2_clk2都是由同一个妈妈(clki)生出来的,频率也都是妈妈的一半,但它们“起步”的时刻可能不同。所以,上面那段话是在提醒你注意这种潜在的、由分频产生的时钟相位关系的不确定性,这在异步电路设计或时钟管理中是必须考虑的关键因素。结果:div2_clk1和div2_clk2的波形完全重合,它们的上升沿和下降沿都发生在同一时刻。

m0_49540263的博客 591

【Spring04】Aop动态代理的使用和原理

AOP动态代理的使用及其@EnableAspectJAutoProxy 开启AOP切面自动代理功能及其实现原理

秦柯的博客 1366

OpenCV计算机视觉实战(12)——图像金字塔与特征缩放

图像金字塔技术通过对原始图像按不同分辨率进行多层次表示,不仅能提升计算效率,还能为图像融合、检测与识别提供多尺度特征。高斯金字塔 (Gaussian Pyramid) 用于构建多级低通图像,拉普拉斯金字塔 (Laplacian Pyramid) 则提取各层之间的细节信息。本节将深入介绍如何使用 OpenCV 构建高斯与拉普拉斯金字塔,并以经典的图像融合案例,展示图像金字塔在特征缩放与融合中的强大应用。

qq_30167691的博客 1403

Opencv项目实战:20 单手识别数字0到5

今天要做的是单手识别数字0到5,通过在窗口展示,实时的展示相应的图片以及文字。在这里,我提供一下识别更多数字的方法(0-10)。首先最简便的是双手识别,完全不用更改代码,把图片处理好就行了;其次,就是按照最上面的那张图片,参数figureup是一个长度为5的列表[0,0,0,0,0],你可以参照着手势将其打印出来,然后将其用if条件判断。当然,在我们这边最常见的还是华北手势表示数字,大家按照自己的习惯来就行。

m0_62919535的博客 2875

spring的aop的动态代理机制都有哪些_Spring学习(4):Spring AOP

Spring AOP说明AOP(Aspect Oriented Pragraming)面向切面编程,AOP采用横向抽取机制,取代了传统纵向继承体系的重复性代码(性能监视、事务管理、安全检查、缓存)。所谓的传统纵向继承体系是指当你需要实现某个功能的时候需要去继承某个类,而横向抽取机制则是通过使用动态代理机制产生一个与之同级的对象,然后在代理对象中进行功能增强。Spring AOP使用纯Java实现,...

weixin_39638304的博客 2160

布尔可满足性问题(SAT)深度研究

布尔可满足性问题(Boolean Satisfiability Problem, SAT)是计算机科学和数理逻辑中的一个核心决策问题。其定义为:对于一个给定的布尔逻辑公式,判断是否存在一组对其变量的真值赋值(即,为每个变量指定真 (True) 或假 (False)),使得该公式的最终计算结果为真。如果存在这样的赋值,则称该布尔公式是可满足的 (satisfiable);否则,称其为不可满足的 (unsatisfiable)。

步子哥的博客 493

Spring AOP中的动态代理实现机制

AOP中的目标对象(target object),也被称为是advised object,是在pointcut处插入aspect时所执行的advice方法中所用到的对象。有点罗嗦,请慢慢体会。任何一个target object都是通过动态代理机制创建的,以实现在运行时被动态插入。本文介绍Spring AOP中的动态代理实现机制,即介绍创建target object的机制。Spring AOP中的动...

成长的足迹 1169

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

IDEA的使用指南

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

Spring学习三:Spring AOP的动态代理的机制

Spring AOP的动态代理机制

weixin_35319963的博客 883

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

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

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

夜雨的博客 1356

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Spring—AOP两种代理机制对比(JDK和CGLib动态代理)

Sprign 动态代理机制 Spirng的AOP的动态代理实现机制有两种,分别是: 1)JDK动态代理: 具体实现原理: 1、通过实现InvocationHandlet接口创建自己的调用处理器 2、通过为Proxy类指定ClassLoader对象和一组interface来创建动态代理 3、通过反射机制获取动态代理类的构造函数,其唯一参数类型就是调用处理器接口类型 4、通过构造

qq1723205668的博客 2万+

Spring AOP简介与底层实现机制——动态代理

欢迎关注专栏:Java架构技术进阶。里面有大量batj面试题集锦,还有各种技术分享,如有好文章也欢迎投稿哦。 AOP简介 AOP (Aspect Oriented Programing) 称为:面向切面编程,它是一种编程思想。AOP 是 OOP(面向对象编程 Object Oriented Programming)的思想延续 AOP采取横向抽取机制,取代了传统纵向继承体系...

xingduan5153的博客 251

Spring AOP 的两种动态代理机制:JDK和CGLib

zSpring AOP简介AOP(Aspect Orient Programming),作为面向对象编程的一种补充,广泛应用于处理一些具有横切性质的系统级服务,如事务管理、安全检查、缓存、对象池管理等。AOP 实现的关键就在于 AOP 框架自动创建的 AOP 代理,AOP 代理则可分为静态代理和动态代理两大类,其中静态代理是指使用 AOP 框架提供的命令进行编译,从而在编译阶段就可生成 AOP 代...

wenlin_xie的专栏 1005

Spring AOP 两种动态代理机制

Spring AOP 使用动态代理技术在运行期织入增强的代码。其使用的动态代理机制有如下两种: 基于 JDK 的动态代理; 基于 CGLib 的动态代理; 之所以需要两种代理机制,很大程度上是因为JDK 本身只提供接口的代理,而不支持类的代理;而 CGLib 很好的弥补了这点,它通过创建子类,在子类中拦截父类的方法并织入横切逻辑,实现对类的代理,但是其不能对目标类中的 final 或 p...

Daz_M的博客 4402

spring的aop的动态代理机制都有哪些_Spring AOP总结

Spring AOP 面向切面编程,就是剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为“Aspect”,也就是切面。简单来说就是于业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少代码量,降低模块间的耦合度,并有利于可操作性和可维护性。Spring AOP核心:切面(aspect):类是对物体特征的抽象,切面是对横切关注点的抽象。横切关注点:对哪...

weixin_39532754的博客 1808

动态代理和Spring AOP机制

Spring核心学习摘要(Day03) Spring整合Junit:通过@RunWith(SpringJUnit4ClassRunner.class)和@ContextConfiguration简化测试,自动加载容器并注入Bean,消除重复代码。 JDBC转账业务实现: 使用JdbcTemplate简化JDBC操作 业务层控制事务保证原子性 需配置数据源和JdbcTemplate 动态代理(AOP基础): 解决代码冗余和耦合问题 两种实现方式:JDK代理(需接口)和CGLIB代理(可代理普通类) 典型应用:

2603_95369890的博客 396

spring的aop的动态代理机制都有哪些_一篇了解什么是Spring AOP

AOP概述AOP(Aspect Orient Programming)是一种设计思想,是软件设计领域中的面向切面编程,它是面向对象编程(OOP)的一种补充和完善。它以通过预编译方式和运行期动态代理方式,实现在不修改源代码的情况下给程序动态统一添加额外功能的一种技术。如图-1所示:AOP与OOP字面意思相近,但其实两者完全是面向不同领域的设计思想。实际项目中我们通常将面向对象理解为一个静态过程(例如...

weixin_39526185的博客 377

IOC、AOP、动态代理、Spring事务、传播机制、隔离级别

Spring中有两种事务,声明式事务和编程式事务 声明式事务:建立在 AOP 之上,本质是对方法前后进行拦截,然后在方法前加入一个事务,执行完方法后根据情况进行提交或回滚。它的优点是不需要通过编程的方式来管理事务,只需要在 xml 配置文件中声明事务即可。一般常用的有两种实现方式,一种是基于< tx> 和< aop>命名空间的方式在 xml 文件中灵活管理事务,代码侵入比...

dl674756321的博客 488

Spring Boot 学习第七天:动态代理机制与Spring AOP 备份

在Java的世界中,实现AOP的主流方式是采用动态代理机制,这点对于Spring AOP也一样。代理机制的主要目的就是为其他对象提供一种dialing以控制对当前对象的访问,用于消除或缓解直接访问对象带来的问题。通过这种手段,一个对象就代表另一个对象的部分功能,我们创建包含当前对象的对象,以便向外界提供功能接口。本篇将关注目前主流的动态代理实现技术,并分析Spring AOP中的代理实现方式。在Spring中,采用的代理机制有两种,即JDK动态代理和CGLIB动态代理。

geminigoth的博客 1112

深入理解 Spring AOP 代理机制:JDK 动态代理与 CGLIB 的对比与选择

JDK 动态代理基于接口,CGLIB 基于继承Spring 默认优先使用 JDK 动态代理,无法使用时切换到 CGLIB可以通过配置强制使用 CGLIB 代理CGLIB 首次生成代理类较慢,但运行时性能更优。

Landcc的博客 1676
上一篇: 动态代理详解
下一篇: ORACLE约束
九月刑天
博客等级 码龄10年 38粉丝 12原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值