Spring1

Spring-01
1、Spring概述
①Spring是一个开源框架
②Spring为简化企业级开发而生,使用Spring开发可以将Bean对象,Dao组件对象,Service组件对象等交给Spring容器来管理,这样使得很多复杂的代码在Spring中开发却变得非常的优雅和简洁,有效的降低代码的耦合度,极大的方便项目的后期维护、升级和扩展。
③Spring是一个IOC(DI)和AOP容器框架。
④Spring的优良特性
[1]非侵入式:基于Spring开发的应用中的对象可以不依赖于Spring的API
[2]控制反转:IOC——Inversion of Control,指的是将对象的创建权交给Spring去创建。使用Spring之前,对象的创建都是由我们自己在代码中new创建。而使用Spring之后。对象的创建都是由给了Spring框架。
[3]依赖注入:DI——Dependency Injection,是指依赖的对象不需要手动调用setXX方法去设置,而是通过配置赋值。
[4]面向切面编程:Aspect Oriented Programming——AOP
[5]容器:Spring是一个容器,因为它包含并且管理应用对象的生命周期
[6]组件化:Spring实现了使用简单的组件配置组合成一个复杂的应用。在 Spring 中可以使用XML和Java注解组合这些对象。
[7]一站式:在IOC和AOP的基础上可以整合各种企业应用的开源框架和优秀的第三方类库(实际上Spring 自身也提供了表述层的SpringMVC和持久层的Spring JDBC)。

2、Spring的模块介绍
在这里插入图片描述

Spring框架分为四大模块:
Core核心模块。负责管理组件的Bean对象
spring-beans-4.0.0.RELEASE.jar
spring-context-4.0.0.RELEASE.jar
spring-core-4.0.0.RELEASE.jar
spring-expression-4.0.0.RELEASE.jar

面向切面编程
spring-aop-4.0.0.RELEASE.jar
spring-aspects-4.0.0.RELEASE.jar

数据库操作
spring-jdbc-4.0.0.RELEASE.jar
spring-orm-4.0.0.RELEASE.jar
spring-oxm-4.0.0.RELEASE.jar
spring-tx-4.0.0.RELEASE.jar
spring-jms-4.0.0.RELEASE.jar

Web模块
spring-web-4.0.0.RELEASE.jar
spring-webmvc-4.0.0.RELEASE.jar
spring-websocket-4.0.0.RELEASE.jar
spring-webmvc-portlet-4.0.0.RELEASE.jar

4、IOC依赖注入
4.1、什么是IOC
IOC 全称指的是 Inverse Of Control 控制反转。

控制反转指的是对象的创建权力被反转了。

使用Spring以前,对象都是自己new 去创建。
使用Spring之后。对象都通过配置Spring的配置文件,然后由Spring容器负责创建。

4.2、什么是DI
DI 指的是Dependency Injection 。是依赖注入的意思。

没有使用Spring的时候对依赖对象的赋值。

public class BookService {
private BookDao bookDao;

public void setBookDao( BookDao bookDao ){
this.bookDao = bookDao;
}

}

使用了Spring之后,就不需要再通过编码来实现对依赖对象的赋值。而是通过配置。

4.3、第一个IOC示例程序 – 通过id获取对象(重点)
实验1:通过IOC容器创建对象,并为属性赋值★

第一步,创建一个Java工程

并导入jar包

commons-logging-1.1.3.jar
spring-beans-4.3.18.RELEASE.jar
spring-context-4.3.18.RELEASE.jar
spring-core-4.3.18.RELEASE.jar
spring-expression-4.3.18.RELEASE.jar

第二步:创建config源码目录

第三步:准备JavaBean对象

public class Person {
private Integer id;
private String name;
private String phone;
private Integer age;

第四步:创建applicationContext.xml配置文件,并配置bean对象

<?xml version="1.0" encoding="UTF-8"?>

<!-- 
	bean标签用来配置一个Bean(bean就是对象)
		class属性设置你要配置的Bean的全类名
		id属性设置一个唯一的标识
 -->
<bean id="p1" class="com.atguigu.pojo.Person">
	<!-- property标签配置属性值
			name设置属性名
			value属性设置值
	 -->
	<property name="id" value="1" />
	<property name="name" value="国哥又有机会帅了" />
	<property name="age" value="18" />
	<property name="phone" value="18610541354" />
</bean>

测试的代码:

@Test
public void test1() throws Exception {
	// applicationContext.xml是Spring的配置文件,
	// 我们需要先有一个Spring容器(Spring IOC 容器),再从容器中获取配置的bean对象
	//ApplicationContext接口表示Spring IOC容器
	// Spring容器(Spring IOC容器) 在初始化的时候需要一个配置文件
	// ClassPathXmlApplicationContext表示从Classpath类路径下加载你指定的配置文件名,生成Spring容器
	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicaionContext.xml");
	// getBean是从Spring容器中获取指定id值的bean对象
	Person person = (Person) applicationContext.getBean("p1");

	System.out.println(person);
}

问题:
1、FileSystemXmlApplicationContext怎么用?
答:跟使用JavaSE的相对路径一样

	// 从文件系统路径中加载指定的xml配置文件生成Spring容器
	ApplicationContext applicationContext = new FileSystemXmlApplicationContext("config/applicaionContext.xml");

2、Bean是在什么时候被创建的?
答:在创建ApplicatiocnContext容器对象的时候创建(默认)

3、如果调用getBean多次,会创建几个?
答:默认创建同一个

常见的错误:
指定的id不存在。找不到bean对象。
在这里插入图片描述

4.4、IOC示例程序 – 通过类型获取对象(重点)
实验2:根据bean的类型从IOC容器中获取bean的实例★

applicationContext.xml配置文件:

<!-- 
	bean标签用来配置一个Bean(bean就是对象)
		class属性设置你要配置的Bean的全类名
		id属性设置一个唯一的标识
 -->
<bean id="p1" class="com.atguigu.pojo.Person">
	<!-- property标签配置属性值
			name设置属性名
			value属性设置值
	 -->
	<property name="id" value="1" />
	<property name="name" value="国哥又有机会帅了" />
	<property name="age" value="18" />
	<property name="phone" value="18610541354" />
</bean>
<bean id="p2" class="com.atguigu.pojo.Person">
	<!-- property标签配置属性值
			name设置属性名
			value属性设置值
	 -->
	<property name="id" value="2" />
	<property name="name" value="国哥帅2次" />
	<property name="age" value="18" />
	<property name="phone" value="18610541354" />
</bean>

测试代码:

@Test
public void test2() throws Exception {
	// 先创建Spring容器对象
	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicaionContext.xml");
	// 通过类型获取Spring容器中的对象
	/**
	 * 如果通过类型查找bean对象。<br/>
	 * 	1、找到一个就直接返回<br/>
	 *  2、找到两个就报错<br/>
	 *  3、没有找到也报错
	 */
	Person person = applicationContext.getBean(Person.class);
	
	System.out.println( person );
}

常见错误说明:
当在applicationContext.xml配置文件中。有多个同Person.class类型实现的时候。

在这里插入图片描述

4.5、IOC示例程序 – 通过构造方法参数名注入值
实验3:通过构造器为bean的属性赋值

applicationContext.xml配置文件:

<bean id="p3" class="com.atguigu.pojo.Person">
	<!-- 
		constructor-arg 标签是指通过构造器赋值
			name设置构造器的参数名
			value设置构造器对应的参数值
	 -->
	<constructor-arg name="id" value="3"/>
	<constructor-arg name="name" value="0105都一样帅"/>
	<constructor-arg name="phone" value="18688886666"/>
	<constructor-arg name="age" value="18"/>
</bean>

测试代码:

@Test
public void test3() throws Exception {
	// 先创建Spring容器对象
	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicaionContext.xml");
	
	Person p3 = (Person) applicationContext.getBean("p3");
	
	System.out.println(p3);
	
}

4.6、IOC示例程序 – index属性指定参数的位置
实验4:通过index属性指定参数的位置

applicationContext.xml配置文件:

<bean id="p4" class="com.atguigu.pojo.Person">
	<!-- Person(Integer id, String name, String phone, Integer age)  -->
	<!-- idnex属性设置参数的索引 
			0 第一个参数
			1 第二个参数
			…… 以此类推
			n 第n+1个参数
	 -->
	<constructor-arg index="0" value="4" />
	<constructor-arg index="1" value="英哥也很帅" />
	<constructor-arg index="2" value="13965484486" />
	<constructor-arg index="3" value="22" />
</bean>

测试代码:

@Test
public void test4() throws Exception {
	// 先创建Spring容器对象
	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicaionContext.xml");
	
	System.out.println( applicationContext.getBean("p4") );
	
}

4.7、IOC示例程序 – 根据参数类型注入
实验5:根据参数类型注入

有两上Person的有参构造器:

public class Person {

private Integer id;
private String name;
private String phone;
private Integer age;

public Person(Integer id, String name, String phone, Integer age) {
	super();
	System.out.println("有参构造器");
	this.id = id;
	this.name = name;
	this.phone = phone;
	this.age = age;
}

public Person(Integer id, String name, Integer age, String phone) {
	super();
	System.out.println("有参构造器");
	this.id = id;
	this.name = name;
	this.phone = phone;
	this.age = age;
}

applicationContext.xml配置文件

<bean id="p4" class="com.atguigu.pojo.Person">
	<!-- Person(Integer id, String name, String phone, Integer age)  -->
	<!-- idnex属性设置参数的索引 
			0 第一个参数
			1 第二个参数
			…… 以此类推
			n 第n+1个参数
	 -->
	<constructor-arg index="0" value="4" />
	<constructor-arg index="1" value="英哥也很帅" />
	<constructor-arg index="2" value="12" />
	<constructor-arg index="3" value="22" />
</bean>


<bean id="p5" class="com.atguigu.pojo.Person">
	<constructor-arg index="0" value="5" type="java.lang.Integer"/>
	<constructor-arg index="1" value="国哥又帅啦" type="java.lang.String"/>
	<constructor-arg index="2" value="12" type="java.lang.String"/>
	<constructor-arg index="3" value="22" type="java.lang.Integer" />
</bean>

测试代码:

@Test
public void test5() throws Exception {
	// 先创建Spring容器对象
	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicaionContext.xml");
	
	System.out.println( applicationContext.getBean("p5") );
	
}

4.8、IOC之 P名称空间
p名称空间,是一种通过简短属性方式调用setXxx方法赋值属性的技术

实验6:通过p名称空间为bean赋值

applicationContext.xml配置文件:

<!-- 
	p名称空间格式是:
		p:属性="值"
 -->
<bean id="p6" class="com.atguigu.pojo.Person"
	p:id="6" p:name="p名称空间赋值" p:age="18" p:phone="18699998888" />	

测试代码:

@Test
public void test6() throws Exception {
	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicaionContext.xml");
	
	System.out.println( applicationContext.getBean("p6") );
}

4.9、测试null值的使用
实验7:测试使用null值

applicationContext.xml配置文件:

<bean id="p7" class="com.atguigu.pojo.Person">
	<property name="id" value="7" />
	<property name="name">
		<!-- null子标签表示赋null值 -->
		<null></null>
	</property>
	<property name="phone" value="1234567312" />
	<property name="age" value="18" />
</bean>

测试代码:

@Test
public void test7() throws Exception {
	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicaionContext.xml");
	
	Person person = (Person) applicationContext.getBean("p7");
	
	System.out.println( person.getName().length() );
}

4.10、IOC之子对象的赋值测试(重点)
实验8:引用其他bean★

创建个新的工程。测试Spring的开发环境。此不重复。请参阅前面,环境搭建。

JavaBean对象

public class Car {
private String carNo;
private String name;

public class Person {
private Integer id;
private String name;
private Car car;

applicationContext.xml配置文件

<bean id="car" class="com.atguigu.pojo.Car">
	<property name="carNo" value="京B531212" />
	<property name="name" value="冰利"/>
</bean>

<bean id="p8" class="com.atguigu.pojo.Person">
	<property name="id" value="8"/>
	<property name="name" value="国哥" />
	<!-- 
		ref属性通过设置id值,将指定的bean对象赋值给属性
	 -->
	<property name="car" ref="car"/>
</bean>

测试代码:

@Test
public void test1() throws Exception {
	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
	
	System.out.println( applicationContext.getBean("p8") );
}

4.11、IOC之内部Bean的使用
实验9:引用内部bean

applicationContext.xml配置文件:

<bean id="car" class="com.atguigu.pojo.Car">
	<property name="carNo" value="京B531212" />
	<property name="name" value="冰利"/>
</bean>

<bean id="p8" class="com.atguigu.pojo.Person">
	<property name="id" value="8"/>
	<property name="name" value="国哥" />
	<!-- 
		ref属性通过设置id值,将指定的bean对象赋值给属性
	 -->
	<property name="car" ref="car"/>
</bean>

<bean id="p9" class="com.atguigu.pojo.Person">
	<property name="id" value="9" />
	<property name="name" value="p9" />
	<property name="car">
		<!-- 内部bean,内部bean只能作为 赋值使用。不能通过容器获取 -->
		<bean id="car02" class="com.atguigu.pojo.Car">
			<property name="carNo" value="京B23421" />
			<property name="name" value="奔池"/>
		</bean>
	</property>
</bean>

测试代码:
@Test
public void test2() throws Exception {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(“applicationContext.xml”);

	System.out.println( applicationContext.getBean("p9") );
	System.out.println( applicationContext.getBean("car") );
	System.out.println( applicationContext.getBean("car02") );
}

常见错误:内部的Bean不能被外部使用

在这里插入图片描述

4.12、IOC之List属性的赋值
实验10:使用list子元素为List类型的属性赋值

给Person类添加List集合类型属性

public class Person {

private Integer id;
private String name;
private Car car;
private List<Object> list;

public List<Object> getList() {
	return list;
}
public void setList(List<Object> list) {
	this.list = list;
}

applicationContext.xml配置文件:

<bean id="p10" class="com.atguigu.pojo.Person">
	<property name="id" value="10" />
	<property name="name" value="p10闪存门"/>
	<property name="list">
		<!-- list标签表示配置一个集合赋值属性 -->
		<list>
			<value>item1</value>
			<value>item2</value>
			<value>item3</value>
			<!-- 内部bean,内部bean只能作为 赋值使用。不能通过容器获取 -->
			<bean id="car03" class="com.atguigu.pojo.Car">
				<property name="carNo" value="京B23421" />
				<property name="name" value="奔池"/>
			</bean>
		</list>
	</property>
</bean>

测试代码:

@Test
public void test3() throws Exception {
	
	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
	
	System.out.println( applicationContext.getBean("p10") );
	
}

4.13、IOC之Map属性的赋值
实验11:使用map子元素为Map类型的属性赋值

给Person对象添加Map集合属性:

public class Person {

private Integer id;
private String name;
private Car car;
private List<Object> list;
private Map<String, Object> map;

public Map<String, Object> getMap() {
	return map;
}
public void setMap(Map<String, Object> map) {
	this.map = map;
}

applicationContext.xml配置文件:

<bean id="p11" class="com.atguigu.pojo.Person">
	<property name="id" value="11" />
	<property name="name" value="p11" />
	<property name="map">
		<!-- 
			map标签表示配置一个map集合给属性赋值
		 -->
		<map>
			<!-- entry是map集合中的每一项 -->
			<entry key="key1" value="value1" />
			<entry key="key2" value="value2" />
			<entry key="key3" value-ref="car" />
		</map>
	</property>
</bean>

测试代码:

@Test
public void test4() throws Exception {
	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
	System.out.println( applicationContext.getBean("p11") );
}

4.14、IOC之Properties属性的赋值
实验12:使用prop子元素为Properties类型的属性赋值

给Person对象,添加Properties类型的属性
public class Person {

private Integer id;
private String name;
private Car car;
private List<Object> list;
private Map<String, Object> map;
private Properties props;

public Properties getProps() {
	return props;
}
public void setProps(Properties props) {
	this.props = props;
}

applicationContext.xml配置文件:

<bean id="p12" class="com.atguigu.pojo.Person">
	<property name="id" value="12" />
	<property name="props">
		<!-- props标签表示配置Properties类型给属性赋值 -->
		<props>
			<prop key="user">root</prop>
			<prop key="password">root</prop>
			<prop key="driver">com.mysql.jdbc.Driver</prop>
			<prop key="url">jdbc:mysql://localhost:3306/test</prop>
		</props>
	</property>
</bean>

测试代码:

@Test
public void test5() throws Exception {
	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
	System.out.println( applicationContext.getBean("p12") );
}

IOC之Set类型属性赋值
给Person添加set类型的属性
public class Person {
private Integer id;
private String name;
private Car car;
private List list;
private Map<String, Object> map;
private Properties props;
private Set set;

public Set<Object> getSet() {
	return set;
}
public void setSet(Set<Object> set) {
	this.set = set;
}

applicationContext.xml配置文件:

<bean id="pset" class="com.atguigu.pojo.Person">
	<property name="id" value="100" />
	<property name="set">
		<!-- 
			set标签配置一个Set集合赋值给属性
		 -->
		<set>
			<!-- value 表示集合中一个字符串值 -->
			<value>value1</value>
			<value>value2</value>
			<!-- ref 表示引用一个bean对象 -->
			<ref bean="car"/>
		</set>
	</property>
</bean>

测试的代码:
@Test
public void test6() throws Exception {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(“applicationContext.xml”);
System.out.println( applicationContext.getBean(“pset”) );
}

4.15、IOC之util 名称空间
util名称空间,可以定义公共的集合类型数据。供外部和内部引用使用。

实验13:通过util名称空间创建集合类型的bean

添加util名称空间:

applicationContext.xml配置文件:

<!-- 使用util名称空间定义一个公共的,可供别人引用的list集合 -->
<util:list id="list01">
	<value>list1</value>
	<value>list2</value>
	<value>list3</value>
	<value>list4</value>
</util:list>
<bean id="p13" class="com.atguigu.pojo.Person">
	<property name="id" value="13"></property>
	<!-- 把list01的id对象。赋值给list属性 -->
	<property name="list" ref="list01"></property>
</bean>

测试代码:

@Test
public void test7() throws Exception {
	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
	
	System.out.println( applicationContext.getBean("p13") );
	System.out.println( applicationContext.getBean("list01") );
	
}

4.16、IOC之级联属性赋值
实验14:给bean的级联属性赋值

applicationContext.xml配置文件

<bean id="car" class="com.atguigu.pojo.Car">
	<property name="carNo" value="京B531212" />
	<property name="name" value="冰利"/>
</bean>

<bean id="p14" class="com.atguigu.pojo.Person">
	<property name="id" value="14" />
	<property name="car" ref="car" />
	<!-- spring中可以使用级联属性方式赋值,但,赋值前这个子对象一定要先有值 -->
	<property name="car.carNo" value="京A123412"/>
</bean>

测试代码:

@Test
public void test8() throws Exception {
	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
	System.out.println( applicationContext.getBean("p14") );
	System.out.println( applicationContext.getBean("car") );
}

常见错误:
级联属性一定要先注入对象。再注入对象的属性
在这里插入图片描述

4.17、IOC之静态工厂方法创建Bean
实验15:配置通过静态工厂方法创建的bean

创建Person的工厂类

public class PersonFactory {

public static Person createPerson() {
	return new Person(15, "静态工厂方法创建的bean对象", null);
}

}

在applicationContext.xml中的配置:

<!-- 
	配置调用静态工厂方法创建Bean对象
		class 配置工厂类的全类名
		factory-method 调用工厂类的哪个方法
 -->
<bean id="p15" class="com.atguigu.factory.PersonFactory" factory-method="createPerson" />

测试的代码:

@Test
public void test9() throws Exception {
	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
	
	System.out.println( applicationContext.getBean("p15") );
}

4.18、IOC之工厂实例方法创建Bean
实验16:配置通过实例工厂方法创建的bean

创建Person工厂

public class PersonFactory {

public Person createPerson2() {
	return new Person(16, "工厂实例方法创建的bean对象", null);
}

}

applicationContext.xml中的配置:

<!-- 1、在spring容器中创建一个bean对象
	 2、配置调用工厂实例的方法
 -->
<bean id="personFactory" class="com.atguigu.factory.PersonFactory"/>
<!-- 
	class属性和factory-method组合是静态工厂方法
	factory-bean 和 factory-method 组合是工厂实例方法
	
	
	factory-bean 使用哪个bean对象做为工厂实例
	factory-method 调用工厂类实例的哪个方法
 -->
<bean id="p16" factory-bean="personFactory" factory-method="createPerson2"></bean>

测试代码:

@Test
public void test10() throws Exception {
	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
	
	System.out.println( applicationContext.getBean("p16") );
	
}

4.19、IOC之FactoryBean接口方式创建对象
实验17:配置FactoryBean接口创建Bean对象

实现FactoryBean接口

public class PersonFacotryBean implements FactoryBean {
/**
* 创建bean对象的方法
/
@Override
public Person getObject() throws Exception {
return new Person(17, “这是FactoryBean接口创建的bean”, null);
}
/
*
* 获取bean的具体类型的方法
/
@Override
public Class<?> getObjectType() {
return Person.class;
}
/
*
* 判断是否是单例的方法
*/
@Override
public boolean isSingleton() {
return true;
}

}

applicationContext.xml配置文件:

<!-- 
	如果指定的Class是实现了Spring的FactoryBean接口,
		Spring容器本身会自动的判断,如果有实现这个FactoryBean接口,
		创建对象的时候,就会调用 getObject()返回对象
 -->
<bean id="p17" class="com.atguigu.factory.PersonFacotryBean"></bean>

测试的代码:

@Test
public void test11() throws Exception {
	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
	
	System.out.println( applicationContext.getBean("p17") );
	
}

4.20、IOC之继承Bean配置
实验18:通过继承实现bean配置信息的重用

applicationContext.xml配置文件:

<bean id="parent" class="com.atguigu.pojo.Person">
	<property name="id" value="100" />
	<property name="name" value="我是父亲" />
	<property name="list">
		<list>
			<value>list1</value>
			<value>list2</value>
			<value>list3</value>
		</list>
	</property>
</bean>
<!-- parent属性设置你要继承哪个id的配置 -->
<bean id="p18" class="com.atguigu.pojo.Person" parent="parent">
	<property name="name" value="我是子"></property>
</bean>

测试代码:

@Test
public void test12() throws Exception {
	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
	
	System.out.println( applicationContext.getBean("p18") );
	
}

4.21、IOC之abstract抽象Bean
abstract的bean配置,就是为了让其他的bean做继承使用。而不能实例化

实验19:通过abstract属性创建一个模板bean

<!-- 
abstract="true"表示这个bean,不能被实例化,而只能被继承使用
 -->
<bean id="parent" class="com.atguigu.pojo.Person" abstract="true">
	<property name="id" value="100" />
	<property name="name" value="我是父亲" />
	<property name="list">
		<list>
			<value>list1</value>
			<value>list2</value>
			<value>list3</value>
		</list>
	</property>
</bean>

测试的代码:

@Test
public void test12() throws Exception {
	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
	
	System.out.println( applicationContext.getBean("parent") );
	System.out.println( applicationContext.getBean("p18") );
	
}

抛的异常
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值