(尚硅谷)21 反射的应用-动态代理-AOP代理的实现

<span style="font-size:18px;">复习
//了解体会反射
package com.atguigu.review;
import java.lang.reflect.Constructor;
import org.junit.Test;
/*
 *java.lang.Class反射的源头 
 * 1)人和一个java源文件经过编译后(java.exe)
 * 声明为一个活多个字节码文件(.class)
 * .class文件经过java.exe解释运行,需要使用JVM的类的加载器加载到缓存(运行时类)
 * 那么加载到缓存中的.class文件就对应这一个Class实例
 * 2)任何一个运行时类之加载一次,生成唯一的Class对象
 * 3)如何获取运行时类对应的大的Class 实例*(三种方法)
 */
public class REFLECT {
	@Test
	public void Test1(){
		//第一种方法,直接调用运行时类的.class属性
		Class clazz1 = person.class;
		System.out.println(clazz1);
		clazz1 = com.atguigu.review.person.class;
		System.out.println(clazz1);
	}
	@Test
	public void Test2(){
		//第二种方法,通过运行时类的getClass()
		person p = new person();
		Class clazz2 = p.getClass();
		System.out.println(clazz2);
	}
	@Test
	public void Test3() throws Exception{
		//第三种,调用class的静态方法forName(String className)报异常
		String className  = "com.atguigu.review.person";
		Class clazz3 = Class.forName(className);
		System.out.println(clazz3);
	}
	@Test
	public void Test4() throws Exception{
		//第四种,通过类的加载器调用
		String className  = "com.atguigu.review.person";
		ClassLoader loader = this.getClass().getClassLoader();
		Class clazz = loader.loadClass(className);
		System.out.println(clazz);
	}
	public Object getObject(String str)throws Exception{
		return Class.forName(str).newInstance();
	}
	@Test
	public void Test5()throws Exception{
		String className  = "com.atguigu.review.person"; 
		Object obj = getObject(className);
	}
	/*
	 * 有了Class类后
	 * 1)用来调用运行时类的对象①调用Class的newInstance()②调用制定的构造器
	 * 2)可以获取运行时类的完整的结构
	 * 3)可以调用云翔时类的属性方法构造器..
	 */
	@Test
	public void Test()throws Exception {
		String className  = "com.atguigu.review.person"; 
		Class clazz = Class.forName(className);
		//newInstance()调用的是空参的构造器
		//大家创建一个类时,通常提供方一个空参的构造器
		Object obj = clazz.newInstance();
		person p = (person)obj;
		System.out.println(p);
	}
	@Test
	public void Test12()throws Exception {
		String className  = "com.atguigu.review.person"; 
		Class clazz = Class.forName(className);
		Constructor con = clazz.getDeclaredConstructor(String.class , int.class);
		con.setAccessible(true);
		Object obj = con.newInstance("王琪",90);
		person p = (person)obj;
		System.out.println(p);
	}
	/*
	 * 可以获取对应运行时类的运行中声明的所有类的结构:属性,方法,构造器,内部类
	 * 父类,接口,包,异常,注解..
	 * File[] getFields():可以获取运行时类中及其父类中所有的public属性
	 * File[] getDeclaredFields():可以获取运行时类本身定义的声明为任何权限的属性
	 */
}
复习实例反射调用---
package com.atguigu.review;
public class Animal {
	public String name ;
	private int id ;  
	private static String desc ;
	public String getName(){
		return name;
	}
	public void setName(String name){
		this.name = name ;
	}
	public int getId(){
		return id;
	}
	public static String getDesc() {
		return desc;
	}
	public static void setDesc(String desc) {
		Animal.desc = desc;
	}
	public void setId(int id) {
		this.id = id;
	}
	public Animal() {
		super();
	}
	public Animal(String name, int id) {
		super();
		this.name = name;
		this.id = id;
	}
	public void show(){
		System.out.println("我是一个动物");
	}
	public static String display(){
		return desc;
	}
	public String info(String style){
		return "我是动物:"+style;
	}
	public String toString (){
		return "Animal"+name+"id "+id;
	}
}
package com.atguigu.review;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import org.junit.Test;
public class TestCLazz {
	@Test
	public void Test1() throws Exception{
		//1.获取Class实例
		Class clazz = Animal.class;
		//2.创建对应的运行时类
		//方法一:newInstance();
		Object obj = clazz.newInstance();
		Animal a = (Animal)obj ;
		System.out.println(a);
		//3.调用制定的运行时类的属性
		Field name = clazz.getDeclaredField("name");
		name.setAccessible(true);
		name.set(a, "Tom猫");
		
		Field id = clazz.getDeclaredField("id");
		id.setAccessible(true);
		id.set(a, 10);
		
		System.out.println(a);
		
		Field desc = clazz.getDeclaredField("desc");
		desc.setAccessible(true);
		desc.set(a, "可爱");
		System.out.println(desc.get(a));
		System.out.println(desc.get(Animal.class));
	}
	@Test
	public void Test2() throws Exception{
		Class clazz = Animal.class;
		//方法二:获取对应的运行时的类对象
		Object returnVal = null;
		Constructor cons = null;
		Animal a =null;
		try {
			cons = clazz.getDeclaredConstructor(String.class , int.class);
			cons.setAccessible(true);
			a= (Animal)cons.newInstance("jerry老鼠",12);
			//获取运行时类中制定的方法
			Method method1 = clazz.getDeclaredMethod("show");
			returnVal = method1.invoke(a);
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println(returnVal);
		
		Method method2 = clazz.getDeclaredMethod("info", String.class);
		method2.setAccessible(true);
		Object obj1 = method2.invoke(a, "老鼠");
		System.out.println(obj1);
		
		Method method3 = clazz.getDeclaredMethod("display");
		method3 .setAccessible(true);
		Object return2 = method3 .invoke(Animal.class);
		System.out.println(return2);
	}
}
package com.atguigu.review;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import org.junit.Test;
public class REFLECT2 {
	@Test
	public void Test1()throws Exception{
		//获取Class实例
		//1.直接调用
		//Class clazz = Animal.class;
		//Class clazz = com.atguigu.review.Animal.class
		//2.调用类对象的实例
		//Animal animal = new Animal();
		//Class clazz = animal.getClass();
		//3调用Class的讲台方法加载器
		//Class clazz = Class.forName(new String("com.atguigu.review.Animal"));
		//4.调用类的加载器
		ClassLoader loader = this.getClass().getClassLoader();
		Class clazz = loader.loadClass(new String("com.atguigu.review.Animal"));
		System.out.println(clazz);
		//2-1创建对应运行时类的对象
		Object obj = clazz.newInstance();
		Animal animal = (Animal)obj;
		System.out.println(animal);
		//3-1调用制定运行时类的属性 
		Field name = clazz.getDeclaredField("name");
		name.setAccessible(true);
		name.set(animal, "王琪");
		System.out.println(name.get(animal));
		
		Field id = clazz.getDeclaredField("id");
		id.setAccessible(true);
		id.setInt(animal, 12);
		System.out.println(animal);
		//调用静态的属性
		Field desc = clazz.getDeclaredField("desc");
		desc.setAccessible(true);
		desc.set(animal, "王琪琪");
		//通过类来调用
		System.out.println(desc.get(Animal.class));
	}
	@Test
	public void Test2()throws Exception{
		ClassLoader loader = this.getClass().getClassLoader();
		Class clazz = loader.loadClass("com.atguigu.review.Animal");
		//调用运行时类的对象的方法
		Object obj = clazz.newInstance();
		Animal animal = (Animal)obj;
		Field name = clazz.getDeclaredField("name");
		name.setAccessible(true);
		name.set(animal, "小老鼠");
		Field age = clazz.getDeclaredField("id");
		age.setAccessible(true);
		age.set(animal, 12);
		System.out.println(animal);
		Method method = clazz.getMethod("info" , String.class);
		method.setAccessible(true);
		System.out.println(method.invoke(animal, "我实际上我没有电话"));
		Field desc = clazz.getDeclaredField("desc");
		desc.setAccessible(true);
		desc.set(Animal.class, "年后回家");
		Method display = clazz.getDeclaredMethod("display");
		display.setAccessible(true);
		System.out.println(display.invoke(Animal.class));
	}
}
Java的代理方法—静态代理—反射代理
 <img src="https://img-blog.csdn.net/20140825203634586?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjY1MTM4OQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" width="300" height="300" alt="" />
1.静态代理方法
package com.atguigu.teacher;
public class NikeClothFactory implements ClothFactory{
	@Override
	public void produceCloth() {
		System.out.println("Nike工厂生产");
	}
}

package com.atguigu.teacher;
//经态代理
public class TestFactory {
	public static void main(String[] args) {
		ClothFactory w = new NikeClothFactory();
		ProxyClothFactory cf = new ProxyClothFactory(w);
		cf.produceCloth();
	}
}
interface ClothFactory{
	void produceCloth();
}
class ProxyClothFactory implements ClothFactory{
	ClothFactory cf ;
	public ProxyClothFactory (ClothFactory cf){
		this.cf = cf ;
	}
	@Override
	public void produceCloth() {
		System.out.println("代理类获取中介费1000");
		cf.produceCloth();
	}
}
1.	动态代理的方法一
动态代理是指客户通过代理类来调用其它对象的方法,并且是在程序运行时根据需要动态创建目标类的代理对象。 动态代理使用场合:调试 远程方法调用 代理设计模式的原理:       使用一个代理将对象包装起来, 然后用该代理对象取代原始对象. 任何对原始对象的调用都要通过代理. 代理对象决定是否以及何时将方法调用转到原始对象上 
package com.atguigu.teacher;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class TestActiveFactory {
	public static void main(String[] args) {
		MyInvocationHannder handler = new MyInvocationHannder();
		RealSubject real = new RealSubject();
		Object obj  = handler.blind(real);//obj即为代理类的对象
		Subject proxy = (Subject) obj;
		proxy.action();//使用代理类的对象调用的被重写的抽象方法
		System.out.println("***********");
		NikeClothFactory nike = new NikeClothFactory();
		Object obj1 = handler.blind(nike);
		ClothFactory proxy1 = (ClothFactory) obj1 ;//Obj1 就是代理类的对象
		proxy1.produceCloth();
	}
}
interface Subject {
	void action();
}
//代理类
class RealSubject implements Subject {
	@Override
	public void action() {
		System.out.println("QI工厂生产");
	}
}
//创建一个实现了InvocationHandler接口的类
class MyInvocationHannder implements InvocationHandler {
	Object obj;//声明的被代理的变量
	public Object blind(Object obj) {
		this.obj = obj;//实例化被代理的变量
		//返回一个与Object 实现了同样的接口的类(即为代理类)
		return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj
				.getClass().getInterfaces(), this);
	}
	/*凡是通过代理类的对象调用其实际接口的被重写的抽象方法时
	 * 都会转换为对如下的Invoke方法的调用
	 * 此invoke()方法返回值即为被重写的抽象方法的返回值
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		Object returnVal = method.invoke(obj, args);
		return returnVal;
	}

}
</span>

<span style="font-size:18px;">package com.atguigu.reflect;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
interface Human {
	void info();
	void fly();
}
public class TestAop {
	public static void main(String[] args) {
		SuperMan su = new SuperMan();
		Object obj = MyProxy.getProxyInstance(su);
		Human h = (Human)obj;
		h.info();
		h.fly();
	}
}
class SuperMan implements Human {
	@Override
	public void info() {
		System.out.println("我是超人我怕人");
	}
	@Override
	public void fly() {
		System.out.println("我要飞!!");
	}
}
class HumanUtil {
	public void method1() {
		System.out.println("-----通用方法1-----");
	}
	public void method2() {
		System.out.println("-----通用方法2-----");
	}
}
class MyInvocationHandler2 implements InvocationHandler {
	Object obj;

	public void setObject(Object obj) {
		this.obj = obj;
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		HumanUtil util =new HumanUtil();
		util.method1();
		Object ret = method.invoke(obj, args);
		util.method2();
		return ret;
	}
}
// 分离
class MyProxy {
	public static Object getProxyInstance(Object obj) {
		MyInvocationHandler2 handler = new MyInvocationHandler2();
		handler.setObject(obj);
		return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj
				.getClass().getInterfaces(), handler);
	}
}</span>


<span style="font-size:18px;">1.网络通信
package com.atguigu.Net;
import java.net.InetAddress;
import java.net.UnknownHostException;
/*
 * 1.网络编程中的两个主要问题
 * 	>如何尊却定位网络上的一台或多台主机
 *  >找到主机后如何可靠高效的进行数据传输
 * 2.实现网络通信的两个要素:①IP地址 ,端口号 ②传输协议
 * 3.如何创建一个InetAdress类对象
 *  ①调用静态的getByName(String hostName)   
 *      ①域名 ②分配了一串数值:IP地址
 *  ②getLocalHost () 获取本地的地址
 *  4.getAdress的常用方法 : getHostName() ; getHostAdress()
 * 	
 */
public class InetAddressTest {
	public static void main(String[] args) {
		//实例化InetAddress对象,getByName();
		InetAddress inet = null;
		try {
			inet = InetAddress.getByName("www.atguigu.com");
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
		//两个方法的使用:getHostName() getHostAdress()
		System.out.println(inet);
		System.out.println(inet.getHostAddress());
		System.out.println(inet.getHostName());
		/*******************************/
		InetAddress inte1  = null;
		try {
			inte1 = InetAddress.getByName("42.121.6.2");
		} catch (UnknownHostException e1) {
			e1.printStackTrace();
		}
		System.out.println(inte1);
		System.out.println(inte1.getHostAddress());
		System.out.println(inte1.getHostName());
		/**********************************/
		InetAddress inet2 = null;
		try {
			inet2 = inet.getLocalHost();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
		System.out.println(inet2);
		System.out.println(inet2.getHostAddress());
		System.out.println(inet2.getHostName());
	}
}
/*************************************************/
package com.atguigu.Net;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
public class TestNet {
	public static void main(String[] args) {
		Thread p1 = new Thread(new test1());
		Thread p2 = new Thread(new test2());
		Thread p3 = new Thread(new test2());
		p2.setName("kehu1");
		p3.setName("kehu2");
		p1.start();
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		p2.start();
	}
}
class test1 implements Runnable{
	public void run(){
		Server s = new Server(9012);
		s.read();
		System.out.println("3333");
	}
}
class test2 implements Runnable{
	public void run(){
		Client c =null;
		try {
			c =new Client(InetAddress.getByName("192.168.0.105") ,9012 );
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
		c.getConnect();
		c.talk();
	}
}
class Client{
	private InetAddress inet ; 
	private int port ; 
	private Socket socket ; 
	public Client (InetAddress inet , int port){
		this.inet = inet ;
		this.port = port;
		System.out.println("客户端 目的地加载完成:"+inet+" "+port);
	}
	public void getConnect(){
		try {
			System.out.println("客户端启动..");
			socket = new Socket(inet, port);
			System.out.println("客户端启动完成!");
		} catch (IOException e) {
			e.printStackTrace();
		}
		System.out.println("连接成功"+inet.getHostName());
	}
	public void talk(){
		BufferedReader bin  = new BufferedReader(new InputStreamReader(System.in)); 
		String str = "";
		BufferedWriter bw = null;
		try {
			bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); 
			System.out.println("开始通话..");
			while((str = bin.readLine())!=null){
				System.out.println(Thread.currentThread().getName());
				if(str.equalsIgnoreCase("by")){
					socket.shutdownOutput();
					break;
				}
				bw.write(str);
				bw.newLine();
				bw.flush();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if(bin!=null){
				try {
					bin.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(bw!=null){
				try {
					bw.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(socket!=null){
				try {
					socket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}
class Server{
	ServerSocket serverSocket =null ;
	Socket socket = null;
	public Server (int doc){
		try {
			System.out.println("服务器加载..");
			serverSocket =new ServerSocket(9012);
			socket =serverSocket.accept();
		} catch (IOException e) {
			e.printStackTrace();
		}
	    System.out.println("waiting..");
	}
	public void read(){
		BufferedReader bin =null;
		try {
			bin = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		String str = null;
		try {
			while((str = bin.readLine())!=null){
				System.out.println(str+"-->"+socket.getInetAddress().getHostName());
			}
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if(bin!=null){
				try {
					bin.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(socket!=null){
				try {
					socket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(serverSocket!=null){
				try {
					serverSocket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
}
/******************************************************************/
package com.atguigu.Net;
import java.net.Socket;
public interface Writer {
	Socket getSocket();
}
package com.atguigu.Net;
import java.net.Socket;
public interface Lisener {
	Socket getSocket();
}
package com.atguigu.Net;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
public class Clinet2 implements Lisener , Writer{
	private Socket socket = null;
	private InetAddress inet = null;
	private int code ;
	public Clinet2(InetAddress inet , int codde){
		this.inet = inet;
		this.code = codde;
		try {
			socket = new Socket(inet , code);
		} catch (IOException e) {
			e.printStackTrace();
		}
		System.out.println("建立客户端...");
	}
	public Socket getSocket() {
		return socket;
	}
	public void setSocket(Socket socket) {
		this.socket = socket;
	}
	public InetAddress getInet() {
		return inet;
	}
	public void setInet(InetAddress inet) {
		this.inet = inet;
	}
	public int getCode() {
		return code;
	}
	public void setCode(int code) {
		this.code = code;
	}
}
package com.atguigu.Net;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server2 implements Lisener , Writer{
	ServerSocket serverSocket2 =null ;
	int codde ; 
	Socket socket ;
	public Server2( int codde){
		this.codde = codde ;
		try {
			serverSocket2 = new ServerSocket( codde );
		} catch (IOException e) {
			e.printStackTrace();
		}
		System.out.println("建立服务器..");
		try {
			socket = serverSocket2.accept();
		} catch (IOException e) {
			e.printStackTrace();
		}
		System.out.println("建立服务器完成..");
	}
	public ServerSocket getServerSocket2() {
		return serverSocket2;
	}
	public void setServerSocket2(ServerSocket serverSocket2) {
		this.serverSocket2 = serverSocket2;
	}
	public int getCodde() {
		return codde;
	}
	public void setCodde(int codde) {
		this.codde = codde;
	}
	@Override
	public Socket getSocket() {
		return socket;
	}
}
package com.atguigu.Net;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;
public class ClentReadThread implements Runnable{
	private Lisener client =null;
	private InputStream in =null ;
	private BufferedReader bn = null;
	private Socket socket;
	public ClentReadThread (Lisener client){
		this.client = client;
		socket = client.getSocket();
		System.out.println("listener waiting..");
	}
	public void run(){
		try {
			in =socket.getInputStream();
		} catch (IOException e) {
			e.printStackTrace();
		}
	   listener();
	}
	public synchronized void listener(){
		try {
			in =socket.getInputStream();
		} catch (IOException e) {
			e.printStackTrace();
		}
			bn = new BufferedReader(new InputStreamReader(in));
			String str = null;
			System.out.println(Thread.currentThread().getName()+" listen..");
			try {
				while(true){
					str = bn.readLine();
					if(str.equalsIgnoreCase("by")){
						socket.shutdownInput();
						break;
					}
					System.out.println(Thread.currentThread().getName()+":"+str);
				}
			} catch (IOException e) {
		}
	}
}
package com.atguigu.Net;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
public class ClentWriterThread implements Runnable{
	private Writer client =null;
	private OutputStream out =null ;
	private BufferedWriter bn = null;
	private Socket socket;
	public ClentWriterThread (Writer client){
		this.client = client;
		socket = client.getSocket();
		System.out.println("Socket联接");
	}
	public void run(){
		System.out.println("开..");
		try {
			out =socket.getOutputStream();
		} catch (IOException e) {
			e.printStackTrace();
		}
		 writer();
	}
	public synchronized void writer(){
		System.out.println("开..");
		try {
			out =socket.getOutputStream();
		} catch (IOException e) {
			e.printStackTrace();
		}
		BufferedReader bin = new BufferedReader(new InputStreamReader(System.in));
		bn = new BufferedWriter(new OutputStreamWriter(out));
		String str = "hehe!!";
		try {
			while((str = bin.readLine())!=null){
				if(str.equalsIgnoreCase("by")){
					socket.shutdownOutput();
					break;
				}
				try {
					bn.write(str);
					bn.newLine();
					bn.flush();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
package com.atguigu.Net;
import java.net.InetAddress;
import java.net.UnknownHostException;
import org.junit.Test;
//2.客户端给服务端发送信息,服务端收到信息打印到控制台,
public class TestNet2 {
	Server2 server ;
	@Test
	public void Servered() {
		 server = new Server2(9090);
		new ClentReadThread(server).listener();
//		Thread serverlisenner = new Thread(new ClentReadThread(server));
//		serverlisenner.setName("serverlisenner");
//		serverlisenner.start();
//		System.out.println("serverlisenner..begin");
	}
	@Test
	public void Clindered(){
		Clinet2 clinder = null ;
		try {
			clinder = new Clinet2(InetAddress.getLocalHost(),9090);
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
		new ClentWriterThread(clinder).writer();
//		Thread ClinderWriter = new Thread(new ClentWriterThread(clinder));
//		ClinderWriter.setName("ClinderWriter");
//		ClinderWriter.start();
//		System.out.println("ClinderWriter..begin");
	}
}
</span>


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值