SpringAOP day04 动态代理机制

1.AOP

1.1 AOP案例引入

1.1.1 数据库事务说明

案例分析:
1. userMapper.insert(User对象)
2. deptMapper.insert(dept对象)
说明: 由于业务需求 要求方法要么同时入库,要么同时回滚.所以必须通过事务进行控制.

1.2 Spring实现事务控制(demo)

1.2.1 代码结构如下

在这里插入图片描述

1.2.2 编辑UserMapper/UserMapperImpl

1).编辑UserMapper
在这里插入图片描述
2).编辑UserMapperImpl

在这里插入图片描述

1.2.3 编辑UserService/UserServiceImpl

1).编辑UserService
在这里插入图片描述
2)编辑UserServiceImpl
在这里插入图片描述

1.2.4 编辑配置类

在这里插入图片描述

1.2.5 编辑测试类

在这里插入图片描述

1.3 代码问题分析

在这里插入图片描述
解决方案: 采用代理模式进行编辑.

1.4 代理模式

1.4.1 生活中代理案例

房屋中介代理模式:
1.房东: 自己手里有房子 需要出租换钱
2.中介机构 1.本职工作 带客户看房/出租房屋 2.收取中介费(服务费)
3.租客: 满足自身需求 租房子

代码思维建模:
1.暴露一个公共的接口(租房子)
2.客户与中介机构进行沟通,中介看起来和房东功能一致.
(代理看起来就是真实的对象)
3.完成用户额外的操作(收取中介费)

1.4.2 代理模式

1).组成部分
1.要求代理者实现与被代理者相同的接口
2.在代理方法中实现功能的扩展
3.用户调用代理对象完成功能(用户认为代理就是目标对象)

2).调用流程
在这里插入图片描述

1.5 静态代理

1.5.1 通过代理模式实现事务控制

角色划分:
1.目标对象target UserServiceImpl类
2.目标方法 method addUser()方法
3.代理: 实现事务控制.
4.代理对象与目标对象实现相同的接口.

1.5.2 修改目标对象名称

在这里插入图片描述

1.5.3 编辑代理类

@Service("userService")
public class StaticProxy implements UserService {
<span class="token comment">//要求引入目标对象</span>
<span class="token annotation punctuation">@Autowired</span> <span class="token comment">//ByType  byName</span>
<span class="token comment">//@Qualifier("target")</span>
<span class="token keyword">private</span> UserService target<span class="token punctuation">;</span>

<span class="token comment">//目的: 对原有方法进行扩展</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">addUser</span><span class="token punctuation">(</span>User user<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
    <span class="token keyword">try</span> <span class="token punctuation">{<!-- --></span>
        System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"事务开始"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        target<span class="token punctuation">.</span><span class="token function">addUser</span><span class="token punctuation">(</span>user<span class="token punctuation">)</span><span class="token punctuation">;</span>
        System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"事务结束"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">Exception</span> e<span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
        e<span class="token punctuation">.</span><span class="token function">printStackTrace</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"事务回滚"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

1.5.4 编辑测试类

@Test
    public void testStaticProxy(){
        ApplicationContext context =
                new AnnotationConfigApplicationContext(SpringConfig.class);
        UserService userService = (UserService) context.getBean("userService");
        User user = new User();
        user.setId(10001);
        user.setName("测试代理机制");
        //执行用户调用
        userService.addUser(user);
    }

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

1.5 静态代理弊端

1).静态代理只针对于某个接口 不能实现所有接口的代理 实用性较差
在这里插入图片描述
2).静态代理中所有的方法,都需要手动的添加事务开始/事务提交代码 代码冗余 不够简洁.
在这里插入图片描述

1.6 动态代理机制

1.6.1 动态代理分类(考题)

1.JDK代理:
要求: 要求目标对象必须实现接口
代理要求: 代理对象也必须实现目标对象的接口
目标对象/代理关系: 目标对象与代理对象兄弟关系.

2.CGlib代理
要求: 不管目标对象是否有接口,都可以为其创建代理对象
代理要求: 要求代理对象必须继承目标对象
目标对象/代理关系: 目标对象与代理对象是父子关系

在这里插入图片描述

1.6.2 编辑JDK动态代理

官网API:
在这里插入图片描述
背会知识点:
1.关于匿名内部类用法说明: 匿名内部类引用外部参数 要求参数必须final修饰
2. 该方法标识 当代理对象执行时,"回调"该方法.
java public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {}
3. 目标方法执行
java result = method.invoke(target,args);

package com.jt.proxy;

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

//能否利用一个工厂动态为目标对象创建代理
public class JDKProxyFactory {

<span class="token comment">//要求用户传递目标对象</span>
<span class="token comment">//关于匿名内部类用法说明:  匿名内部类引用外部参数 要求参数必须final修饰</span>
<span class="token keyword">public</span> <span class="token keyword">static</span> Object <span class="token function">getProxy</span><span class="token punctuation">(</span><span class="token keyword">final</span> Object target<span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
    <span class="token comment">//1.调用java API实现动态代理</span>
    <span class="token comment">/**
     *  参数分析: 3个参数
     *      1.ClassLoader loader, 类加载器(获取目标对象的Class)
     *      2.类&lt;?&gt;[] interfaces,  JDK代理要求 必须有接口
     *                             java中可以多实现
     *      3.InvocationHandler h  对目标方法进行扩展
     */</span>
    <span class="token comment">//1.获取类加载器</span>
    ClassLoader classLoader <span class="token operator">=</span> target<span class="token punctuation">.</span><span class="token function">getClass</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getClassLoader</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//2.获取接口数组</span>
    Class<span class="token punctuation">[</span><span class="token punctuation">]</span> interfaces <span class="token operator">=</span> target<span class="token punctuation">.</span><span class="token function">getClass</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getInterfaces</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//3.通过动态代理创建对象</span>
    Object proxy <span class="token operator">=</span> Proxy<span class="token punctuation">.</span><span class="token function">newProxyInstance</span><span class="token punctuation">(</span>classLoader<span class="token punctuation">,</span> interfaces<span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">InvocationHandler</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>

        <span class="token comment">//invoke方法: 代理对象调用方法时invoke执行,扩展方法的编辑位置</span>
        <span class="token annotation punctuation">@Override</span>
        <span class="token keyword">public</span> Object <span class="token function">invoke</span><span class="token punctuation">(</span>Object proxy<span class="token punctuation">,</span> Method method<span class="token punctuation">,</span> Object<span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span> <span class="token keyword">throws</span> Throwable <span class="token punctuation">{<!-- --></span>
            <span class="token comment">// result 标识目标方法执行的返回值</span>
            Object result <span class="token operator">=</span> null<span class="token punctuation">;</span>
            <span class="token keyword">try</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">//添加事务的控制</span>
                System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"事务开始"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token comment">//执行目标方法</span>
                <span class="token comment">// target真实的目标对象,method方法对象,args方法参数</span>
                result <span class="token operator">=</span> method<span class="token punctuation">.</span><span class="token function">invoke</span><span class="token punctuation">(</span>target<span class="token punctuation">,</span>args<span class="token punctuation">)</span><span class="token punctuation">;</span>
                System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"事务提交"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span><span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">Exception</span> e<span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
                e<span class="token punctuation">.</span><span class="token function">printStackTrace</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"事务回滚"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">return</span> result<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token keyword">return</span> proxy<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

1.6.3 JDK动态代理执行过程

在这里插入图片描述

1.7 动态代理优势

将公共的部分写到动态代理中,之后其他的业务类调用即可

1.7.1 编辑DeptService/DeptServiceImpl

1).编辑DeptService
在这里插入图片描述
2).编辑DeptServiceImpl
在这里插入图片描述

1.7.2 编辑测试类

public class TestDept {
<span class="token annotation punctuation">@Test</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">testTx</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
    <span class="token comment">//1.获取目标对象</span>
    ApplicationContext context <span class="token operator">=</span>
            <span class="token keyword">new</span> <span class="token class-name">AnnotationConfigApplicationContext</span><span class="token punctuation">(</span>SpringConfig<span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    DeptService target <span class="token operator">=</span> <span class="token punctuation">(</span>DeptService<span class="token punctuation">)</span> context<span class="token punctuation">.</span><span class="token function">getBean</span><span class="token punctuation">(</span><span class="token string">"deptService"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//2.获取代理对象</span>
    DeptService deptService <span class="token operator">=</span> <span class="token punctuation">(</span>DeptService<span class="token punctuation">)</span> JDKProxyFactory<span class="token punctuation">.</span><span class="token function">getProxy</span><span class="token punctuation">(</span>target<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//通过代理对象 调用方法  扩展了方法!!!!!</span>
    deptService<span class="token punctuation">.</span><span class="token function">addDept</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">//invoke</span>
<span class="token punctuation">}</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

1.8 动态代理实现方案(二)

1.8.1 业务需求

要求对Service层的方法记录其执行的时间!!! 通过执行时间的长短 进行针对性的优化!!!
要求: service中 有 addUser方法/deleteUser方法.
要求代码结构扩展性好,耦合性低.
做完1000块!!!

1.8.2 编辑UserService/UserServiceImpl

1).编辑UserService

public interface UserService {
<span class="token keyword">void</span> <span class="token function">addUser</span><span class="token punctuation">(</span>User user<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">void</span> <span class="token function">deleteUser</span><span class="token punctuation">(</span>User user<span class="token punctuation">)</span><span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

2).编辑UserServiceImpl

@Service("target")
public class UserServiceImpl implements UserService{
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">addUser</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
    System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"新增用户"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">deleteUser</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
    System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"删除用户"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

1.8.3 编辑代理工厂

package com.jt.proxy;

import javax.annotation.PostConstruct;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class JDKProxyFactory {

<span class="token comment">//编辑静态方法获取代理对象</span>
<span class="token keyword">public</span> <span class="token keyword">static</span> Object <span class="token function">getProxy</span><span class="token punctuation">(</span><span class="token keyword">final</span> Object target<span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
    <span class="token comment">//3个参数  1.类加载器  2.对象的接口</span>
    ClassLoader classLoader <span class="token operator">=</span> target<span class="token punctuation">.</span><span class="token function">getClass</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getClassLoader</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    Class<span class="token punctuation">[</span><span class="token punctuation">]</span> interfaces <span class="token operator">=</span> target<span class="token punctuation">.</span><span class="token function">getClass</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getInterfaces</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    Object proxy <span class="token operator">=</span> Proxy<span class="token punctuation">.</span><span class="token function">newProxyInstance</span><span class="token punctuation">(</span>classLoader<span class="token punctuation">,</span> interfaces<span class="token punctuation">,</span>
            <span class="token keyword">new</span> <span class="token class-name">InvocationHandler</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">//代理对象执行目标方法时执行</span>
                <span class="token annotation punctuation">@Override</span>
                <span class="token keyword">public</span> Object <span class="token function">invoke</span><span class="token punctuation">(</span>Object proxy<span class="token punctuation">,</span> Method method<span class="token punctuation">,</span> Object<span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span> <span class="token keyword">throws</span> Throwable <span class="token punctuation">{<!-- --></span>

                    <span class="token comment">//让用户执行目标方法</span>
                    Long startTime <span class="token operator">=</span> System<span class="token punctuation">.</span><span class="token function">currentTimeMillis</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//开始时间</span>
                    <span class="token comment">//执行目标方法 获取返回值 可能为null</span>
                    Object result <span class="token operator">=</span> method<span class="token punctuation">.</span><span class="token function">invoke</span><span class="token punctuation">(</span>target<span class="token punctuation">)</span><span class="token punctuation">;</span>
                    Long endTime <span class="token operator">=</span> System<span class="token punctuation">.</span><span class="token function">currentTimeMillis</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">//结束时间</span>
                    <span class="token comment">//根据项目经理要求 给程序预留bug 后期维护时删除 不友好</span>
                    Thread<span class="token punctuation">.</span><span class="token function">sleep</span><span class="token punctuation">(</span><span class="token number">2000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"程序执行:"</span><span class="token operator">+</span><span class="token punctuation">(</span>endTime<span class="token operator">-</span>startTime<span class="token punctuation">)</span><span class="token operator">+</span><span class="token string">"毫秒"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token comment">//将返回值传递给调用者</span>
                    <span class="token keyword">return</span> result<span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
            <span class="token punctuation">}</span><span class="token punctuation">)</span>  <span class="token punctuation">;</span>

    <span class="token keyword">return</span> proxy<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

1.8.4 编辑测试案例

public class TestSpring {
<span class="token annotation punctuation">@Test</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">test01</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
    ApplicationContext context <span class="token operator">=</span>
            <span class="token keyword">new</span> <span class="token class-name">AnnotationConfigApplicationContext</span><span class="token punctuation">(</span>SpringConfig<span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//1.获取目标对象</span>
    UserService target <span class="token operator">=</span> <span class="token punctuation">(</span>UserService<span class="token punctuation">)</span> context<span class="token punctuation">.</span><span class="token function">getBean</span><span class="token punctuation">(</span><span class="token string">"target"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//2.获取代理对象</span>
    UserService proxy <span class="token operator">=</span> <span class="token punctuation">(</span>UserService<span class="token punctuation">)</span> JDKProxyFactory<span class="token punctuation">.</span><span class="token function">getProxy</span><span class="token punctuation">(</span>target<span class="token punctuation">)</span><span class="token punctuation">;</span>
    System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>proxy<span class="token punctuation">.</span><span class="token function">getClass</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//3.调用业务方法</span>
    proxy<span class="token punctuation">.</span><span class="token function">addUser</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

1.9 业务案例3

要求进行日志控制 1000块
要求方法执行时,获取方法名,及所在类的名称 进行控制台输出. 以及方法的执行时间

作业

1).熟练编辑3层代码结构 5遍

# 系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 例如:第一章 Python 机器学习入门之pandas的使用

提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

提示:这里可以添加本文要记录的大概内容:
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


提示:以下是本篇文章正文内容,下面案例可供参考

一、pandas是什么?

示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。

二、使用步骤

1.引入库

代码如下(示例):

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
import  ssl
ssl._create_default_https_context = ssl._create_unverified_context

2.读入数据

代码如下(示例):

data = pd.read_csv(
    'https://labfile.oss.aliyuncs.com/courses/1283/adult.data.csv')
print(data.head())

该处使用的url网络请求的数据。


总结

提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值