2021-05-08

2021/5/8 1-Spring的IoC-DI容器
file:///C:/Users/Administrator/Desktop/Spring/1-Spring的IoC-DI容器.html 1/34
Spring的IoC容器
IoC在程序开发中,实例的创建不再由调用者管理,而是由Spring容器创建。Spring容器会负责控制程序
之间的关系,而不是由程序代码直接控制,因此,控制权由程序代码转移到了Spring容器中,控制权发
生了反转,这就是Spring的IoC思想
基础理论回顾
Spring是一个轻量级的控制反转IoC/DI依赖注入和面向切面AOP的开源容器框架,是一个开源的
Java/Java EE全功能栈full-stack的应用程序框架,以Apache许可证形式发布
Spring是一个轻量级的DI/IoC和AOP容器框架。存在的目的是用于构建轻量级的JavaEE应用。
Spring以一种非侵入式的方式来管理你的代码,Spring提倡”最少侵入”,这也就意味着你可以适当的时
候安装或卸载Spring
目的:解决企业应用开发的复杂性
功能:使用基本的JavaBean代替EJB,并提供了更多的企业应用功能
范围:任何Java应用
简单来说,Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架
Spring基础就是IoC/DI容器
简单来说,Spring是一个分层的JavaSE/EE full-stack(一站式解决方案) 轻量级开源框架
Spring的模块化结构
6个模块20多个子项目组成的,Spring的模块化是很强的,各个功能模块都是独立的,可以选择的使用
public class BeanFactory{
  private static final Map<String,Object> map=new HashMap<>();
  public static Object getBean(String id){}
} 1234
2021/5/8 1-Spring的IoC-DI容器
file:///C:/Users/Administrator/Desktop/Spring/1-Spring的IoC-DI容器.html 2/34
IoC(Inversion of Control):其思想是反转资源获取的方向
DI(Dependency Injection) — 即组件以一些预先定义好的方式(例如: setter 方法)接受来自如容器的资源
注入. 相对于 IoC 而言,这种表述更直接
bean是Spring管理的基本单位,在Spring的应用中,所有的组件都是bean,bean包括数据源、
Hibernate的SessionFactory及事务管理器等。 Spring里的bean是非常广义的概念,任何的Java对
象,Java组件都可被当成bean处理。甚至这些组件并不是标准的JavaBean。整个应用中各层的对
象都处于 Spring 的管理下,这些对象以 bean 的方式存在,Spring负责创建 bean 实例,并管理其
生命周期。
bean在Spring容器中运行时,无须感受Spring容器的存在,一样可以接受Spring的依赖注入,包括
bean属性的注入,合作者的注入及依赖关系的注入等
Spring优势
低侵入/低耦合(降低组件之间的耦合度,实现软件各层之间的解耦。)
声明式事务管理
方便集成其他框架
降低JavaEE开发难度
Spring框架中包括JavaEE 三层的每一层的解决方案 (一站式)
Spring功能
Spring能帮我们根据配置文件创建及组装对象之间的依赖关系
Spring 面向切面编程能帮助我们无耦合的实现日志记录,性能统计,安全控制
Spring能非常简单的帮我们管理数据库事务
Spring还提供了与第三方数据访问框架(如Hibernate、JPA)无缝集成,而且自己也提供了一套
JDBC访问模板,来方便数据库访问
Spring还提供与第三方Web(如Struts、JSF)框架无缝集成,而且自己也提供了一套Spring MVC
框架,来方便web层搭建
2021/5/8 1-Spring的IoC-DI容器
file:///C:/Users/Administrator/Desktop/Spring/1-Spring的IoC-DI容器.html 3/34
Spring能方便的与Java EE(如Java Mail、任务调度)整合,与更多技术整合(比如缓存框架)。
Spring的核心思想
不重复发明轮子理论
锤子理论
A a = new A1()然后通过a来调用接口的方法,对于C来说是主动实例化对象,直接获取依赖。
这种实现方法的缺点:
更换实现需要重新编译源代码
很难更换实现,很难测试
耦合实例生产者和实例消费者
工厂模式
设计模式属于创建型模式,它提供了一种创建对象的最佳方式
主要解决:主要解决接口实现的选择问题。
优点: 1、一个调用者想创建一个对象,只要知道其名称就可以了。 2、扩展性高,如果想增加一个产
品,只要扩展一个工厂类就可以。 3、屏蔽产品的具体实现,调用者只关心产品的接口
缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,
在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。
工厂模式中产品可扩展,但是产品只能一种系列
抽象工厂模式
抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他
工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式
主要解决:提供一个创建一系列相关或相互依赖对象的接口,解决接口实现选择的问题
优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的
对象
缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具
体的里面加代码。
功能扩展
产品的系列不可扩展,引入资源文件,使用反射创建字串所指代的对象。
但是properties文件在IDE中缺乏语法检查,所以考虑采用xml作为配置
Spring的工厂模式实现
Spring框架最重要是提供了以类似上面xml+BeanFactory的方式管理配置在xml文件中的受管Bean
XML配置
XML可扩展标记语言,是一种依靠与SGML由w3c定义出来的标记语言。XML允许用户自定义标签,提供
了2种方式说明其中的标签: dtd[ 文档类型定义]或者xsd(模式类型定义)。
Xml文件可以分为无效、良构和有效的3种,一般对xml文件的解析至少要求良构的。
XML文件作用
2021/5/8 1-Spring的IoC-DI容器
file:///C:/Users/Administrator/Desktop/Spring/1-Spring的IoC-DI容器.html 4/34
存储数据
传递数据,即服务器以XML的形式传输数据
软件配置,即通过配置XML文件,通知应用程序如何处理业务
XML和Html的关系
XML 不是 HTML 的替代。
XML 和 HTML 为不同的目的而设计:
XML 被设计用来传输和存储数据,其焦点是数据的内容。
HTML 被设计用来显示数据,其焦点是数据的外观。
HTML 旨在显示信息,而 XML 旨在传输信息。
XML文件的解析模型
DOM
DOM是W3C处理XML的标准API,它是许多其它与XML处理相关的标准的基础,不仅是Java,其它诸如
Javascript,PHP,MS .NET 等等语言都实现了该标准, 成为了应用最为广泛的XML处理方式
形成树结构,直观好理解
解析过程中树结构保留在内存中,方便修改
当xml文件较大时,对内存消耗比较大,容易影响解析性能并造成内存溢出
适用范围:小型XML文件解析、需要全解析或者大部分解析XML、需要修改XML树内容以生成自己
的对象模型
SAX
SAX使用了最少的系统资源和最快速的解析方式对XML处理提供了支持。 但随之而来繁琐的查找方式也
给广大程序员带来许多困扰,常常令人头痛不已
采用事件驱动模式,对内存消耗比较小
适用于只需要处理xml中数据时
不易编码
很难同时访问同一个xml文件中的多处不同位置
适用范围:大型XML文件解析、只需要部分解析或者只想取得部分XML树内容、有XPath查询需求、有
自己生成特定XML树对象模型的需求
Spring基本框架结构
Spring是一种JavaEE开发中的一站式解决方案,所以其中包含的内容比较多,为了避免在应用中添加无
用功能,所以Spring采用了非强制性的模块化结构,在具体应用中,可以根据应用所需要的功能进行选
择添加
Spring3.x分为6大模块,Spring的模块化是很强的,各个功能模块都是独立的,可以选择的使用
2021/5/8 1-Spring的IoC-DI容器
file:///C:/Users/Administrator/Desktop/Spring/1-Spring的IoC-DI容器.html 5/34
Core模块是Spring应用的基础,提供了最基本的IoC/DI容器的支持和实现
AOP模块建立在Core模块的基础上,提供了AOP技术的支持,以简化AOP编程的复杂度
DAO和ORM模块建立在AOP的基础上,DAO提供了dao模式编程的简化支持,ORM提供了整合持久
层框架的支持。同时在AOP的基础上给数据库访问提供了声明式事务的支持
JEE模块建立在Core模块的基础上,提供了针对EJB\邮件javaMail等企业级应用支持
Web模块建立在core模块的基础上,提供了整合其它表现层框架【例如Struts\JSF等】的支持,同
时提出了自己的表现层框架SpringMVC[针对Struts1提出的]
Spring4.x分为6大模块,包括20多个子项目
Core container核心容器:beans core context context-support expression
AOP和apects提供AOP编程技术支持: aop aspects,另外还有其它的不是Spring的jar
Data Access/Integration针对DAO编程和ORM整合的支持: jdbc orm tx
Web提供了整合表现层框架和对应的web解决方案SpringMVC:web webmvc
2021/5/8 1-Spring的IoC-DI容器
file:///C:/Users/Administrator/Desktop/Spring/1-Spring的IoC-DI容器.html 6/34
Instrumentation底层基础,是一种没有图形界面的,具有启动能力的,用于监控其他类的工具类
Test提供了单元测试的支持,要求junit4.8+版本
Spring的全方位应用程序框架
ssm=SpringMVC+Spring+MyBatis [一般开发中常用,尤其是互联网应用开发类型的公司,一般中
小型快速开发中应用]
ssh[2]=Struts2+Spring+Hibernate [使用较少,一般在大型软件公司中长期使用,考试居多]
概述IoC
IoC控制反转Inversion of control不是什么技术,而是一种设计思想。在Java开发中,IoC意味着将设计
好的对象交给容器控制,而不是传统的在你的对象内部直接控制。IoC是一种让服务消费者不直接依赖于
服务提供者的组件设计方式,是一种减少类与类之间依赖的设计原则
IoC用途
IoC不是一种技术,只是一种思想,一个重要的面向对象编程的法则,它能指导如何设计出松耦合、更优
良的程序。传统应用程序都是在类内部主动创建依赖对象,从而导致类与类之间高耦合,难于测试; 有了
IoC容器后, 把创建对象和查找依赖对象的控制权交给了容器, 由容器进行注入组合对象, 所以对象与对象
之间是松散耦合, 这样也方便测试, 利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活.
其实,IoC对编程带来的最大改变不是从代码上,而是从思想上,发生了"主从换位"的变化,应用程序原本
是老大,要获取什么资源都是主动出击,但是在IoC/DI思想中,应用程序就变成被动的了,被动的等待IoC容
器来创建并注入它所需要的资源了
基本概念
IoC容器
简单的理解就是,实现IoC思想,并提供对象创建、对象装配以及对象生命周期管理的软件就是IoC
容器
IoC理解
1、应用程序无需主动new对象;而是描述对象应该如何被创建即可,IoC容器帮你创建,即被动实例化; 2、应用程序不需要主动装配对象之间的依赖关系,而是描述需要哪个服务,IoC容器会帮你装配,被动
接受装配; 3、主动变被动,以前创建对象、装配对象的依赖关系都是由应用程序主动完成,现在变成被动了由IoC
容器来完成
4、应用程序不知道依赖的具体实现,只知道需要提供某类服务的对象,达到并松散耦合; 5、是一种让服务消费者不直接依赖于服务提供者的组件设计方式,是一种减少类与类之间依赖的设计原

使用Ioc/DI容器开发需要改变思路
2021/5/8 1-Spring的IoC-DI容器
file:///C:/Users/Administrator/Desktop/Spring/1-Spring的IoC-DI容器.html 7/34
1、应用程序不主动创建对象,但是要描述创建它们的方法
2、在应用程序代码中不直接进行服务的装配,但是要描述哪一个组件需要哪一项服务,由容器负责将这
些装配在一起
也就是说:所有的组件都是被动的,组件初始化和装配都由容器负责,应用程序只是获取相应的组件
后,实现应用的功能即可
概述DI
DI依赖注入Dependency Injection即组件之间的依赖关系由容器在运行期决定,形象的来说,即由容器
动态的将某种依赖关系注入到组件之中. 依赖注入的目标并非为软件系统带来更多的功能,而是为了提升
组件重用的概率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制只需要通过简单的配置,
而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不用关心具体的资源来自何处、由
谁实现
控制反转和依赖注入
它们不是同一个概念,但是它们是同一个概念的不同角度的描述
控制反转IoC从 IoC容器的角度来说
依赖注入DI从应用程序的角度来说
IoC/DI的基本思想
1、把程序之间的依赖关系去掉
2、把程序对象设置到IoC/DI容器的配置中,作为Bean来统一管理
3、由IoC/DI容器来管理Bean的创建、实例化
4、由IoC/DI容器来把Bean之间的关系注入到需要这些关系的对象里面
简而言之:就是把对象之间的依赖关系全部去掉,由IoC/DI容器来管理对象和对象之间的依赖关系,实
现对象之间的松散耦合
使用IoC/DI容器开发需要改变思路
1、应用程序不主动创建对象,但是要描述创建它们的方法 2、在应用程序代码中不直接进行服务的装
配,但是要描述哪一个组件需要哪一项服务,由容器负责将这些装配在一起 也就是说:所有的组件都是
被动的,组件初始化和装配都由容器负责,应用程序只是获取相应的组件后,实现应用的功能即可
受管bean的定义方法
配置方式有3种: XML、xml+Annoration、JavaConfig
Bean的创建方式:通过全类名(反射)、通过工厂方法(静态工厂方法 & 实例工厂方法)、
FactoryBean
受管bean的配置方式
定义对应的类,并进行配置,将对象纳入到容器中进行管理(受管bean)
【(Spring2.5-)xml配置 xml+注解配置 (Spring4.0+建议)JavaConfig类配置】
xml配置:适合实现类来源于第三方类库,可以引入对应的命名空间简化配置
注解配置:适合实现类是当前项目开发的,可以直接在Java类中使用基于注解的配置
JavaConfig类配置:优势在于可以通过代码方式控制bean初始化的整体逻辑
2021/5/8 1-Spring的IoC-DI容器
file:///C:/Users/Administrator/Desktop/Spring/1-Spring的IoC-DI容器.html 8/34
Spring的核心配置文件applicationContext.xml
XML受管bean

没有任何特殊要求,一般Java类都可以充当JavaBean,一般需要无参构造器,private属性和public的
get/set方法, 非final类
id为在代码中引用的名称,唯一,且可以为多个,利用逗号、分号、或空格分隔
class指向全类名,spring就是根据全类名,通过反射生成一个实例对象,id为这个实例对象的引
用,所以必须在这个类中添加默认的构造方法,并且属性要有setter方法
scope
singleton单例,是默认属性:Spring将Bean放入Spring IoC容器的缓存池中,并将Bean引用
返回给调用者,spring IoC容器负责对这些Bean进行后续的生命管理。BeanFactory只管理一
个共享的实例。所有对这个特定bean的实例请求,都导致返回这个唯一bean实例的引用。即
每次拿到的对象都是引用的同一个地址的对象。当一个bean被标识为singleton时候,spring
的IoC容器中只会存在一个该bean
prototype原型:不管是BeanFactory或者ApplicationContext都是延迟加载使用的。每次对
这个bean的实例请求都会导致一个新的实例的创建。当用户需要不受其他用户对象影响的对
象或有类似的需求时,这是一个较理想的解决办法。即每次拿到的对象都是引用的不同地址的
对象。相当于一个new的操作。清除prototype作用域的对象并释放任何prototype bean所持
有的昂贵资源,都是客户端代码的职责
以下3种scope都使用的较少,有request\session\global session,类似于JavaEE里面的
request和session。在使用SpringMVC是可能会用到
request表示针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP
request内有效
session表示一个用户【客户】对应一个新的bean
global session作用域类似于标准的HTTPSession作用域,不过仅仅在基于portlet的web
应用中才有意义
注意:对于struts2中的Action来说需要指明scope=prototype,因为struts2的Action要求是多实
例、单线程的
建议:private属性public的get/set方法、 无参构造器、 非fianl类
所谓依赖注入,是指程序运行过程中,如果需要调用另一个对象协助时,无须在代码中创建被调用
者,而是依赖于外部的注入 <bean id=”” class=”” p:属性名称-ref=”另外受管bean的名称”/>
xml+Annoration

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


1234567
2021/5/8 1-Spring的IoC-DI容器
file:///C:/Users/Administrator/Desktop/Spring/1-Spring的IoC-DI容器.html 9/34
一类是使用Bean,即是把已经在xml文件中配置好的Bean拿来用,完成属性、方法的组装;比如
@Autowired , @Resource,可以通过byTYPE(@Autowired)、byNAME(@Resource)的方式获取
Bean
一类是注册Bean,@Component , @Repository , @ Controller , @Service , @Configration这些注解都
是把你要实例化的对象转化成一个Bean,放在IoC容器中,等要用的时候,它会和上面的@Autowired ,
@Resource配合到一起,把对象、属性、方法完美组装
相关注解
1、@Service用于标注业务层组件
2、@Controller用于标注控制层组件(如struts2中的action)
3、@Repository用于标注数据访问组件,即DAO组件. 4、@Component泛指组件,当组件不好归类的时候,可以使用这个注解进行标注
可以添加参数value="名称"或者直接定义字串类型名称。如果不定义名称,则默认受管bean的名称为类
名称,首字母小写.
@Scope(“prototype”)来改变范围设置,不设置则默认为singleton
定义受管bean的方法
@Component 这里用于声明这个类是受管bean,默认名称为类名称,首字母小写。如果需要可以添加
属性配置(value=”名称”)人为设置受管bean的id名称,注意这里的value=可以省略
@Repository(“userDao”)
public class UserDaoImpl implements IUserDao {
public void pp() {
System.out.println(“pppppppp”);
} }

<context:component-scan base-package=“com.yan”>
   
<context:include-filter type=“annotation”
expression=“org.springframework.stereotype.Repository” />
</context:component-scan>
ApplicationContext ac = new
ClassPathXmlApplicationContext(“applicationContext.xml”);//使用自动装配则不能
使用BeanFactory,应该使用ApplicationContext接口
IUserDao userDao=ac.getBean(“userDao”,IUserDao.class);//名称对应的是在
UserDaoImpl上的@Repository定义的名称
userDao.pp();
123456789
10
11
12
13
14
15
16
17
18
public class A {} 1
<context:component-scan base-package=“com.yan.a5”/> 配置自动组件扫描,如果类上有
4种注解@component @service @repository @controller中的一种,这个bean就是受管bean
1
2021/5/8 1-Spring的IoC-DI容器
file:///C:/Users/Administrator/Desktop/Spring/1-Spring的IoC-DI容器.html 10/34
注入被依赖对象
@Resource
JavaConfig
Bean的创建方式
配置Bean其实就是使用DI依赖注入将Bean交给IoC容器管理,实现IoC控制反转达到解耦的过程
通过全类名反射创建
通过工厂方法创建
一般用于整合旧有系统或者Spring整合其它框架时
静态工厂
@Component
public class A {
@ javax.annotation.Resource(name=“b”)  //是JSR250规范定义,注入方式采用的是
byName注入,注入设置可以定义在属性上【但是不需要对应的set方法】,也可以定义在set方法上.
其中name值为注入的受管bean的名称。如果不定义name则按照类型自动装配byType
private B b;
@org.springframework.beans.factory.annotation.Autowired//默认按照类型自动装
配,可以添加设置required = true表示这个属性必须注入false表示可有可无。如果两个同类型
的受管bean,系统先尝试按照属性名称进行注入;可以添加注解@Qualifier设置按照名称自动装配
@Autowired(required = true)
@Qualifier(“now”)
private Date now1;
//@Inject是JSR330的规范,需要添加jar包支持
123456789
10
11
@Configuration // 用于声明当前类是一个配置类
public class MyConfig {
@Bean // 用于声明返回值就是一个受管bean,方法名称就是受管bean的id
public A1 aa() {
return new A1();
} } 1234567
ApplicationContext ac=new
AnnotationConfigApplicationContext(MyConfig.class);
A1 aa=ac.getBean(“aa”, A1.class);
aa.pp();
123 1
2021/5/8 1-Spring的IoC-DI容器
file:///C:/Users/Administrator/Desktop/Spring/1-Spring的IoC-DI容器.html 11/34
实例工厂方法
先创建DaoFactrory对象userDaoFactory,然后获取userDao对象时,是通过调用userDaoFactory对象
的getUserDao方法获取
BeanFactory和ApplicationContext
Spring 提供了两种类型的IoC容器实现
BeanFactory是IoC 容器的基本实现,ApplicationContext 提供了更多的高级特性,是
BeanFactory的子接口
针对单例类型的受管bean,BeanFactory默认采用延迟加载,ApplicationContext默认采用立即加

BeanFactory 是 Spring 框架的基础设施,面向 Spring 本身;ApplicationContext 面向使用
Spring 框架的开发者,几乎所有的应用场合都直接使用 ApplicationContext 而非底层的
BeanFactory
获取IoC容器的引用(不使用测试框架)
public class DaoFactory{
  public static IUserDao getUserDao(){
      return UserDaoImpl();
  }
} 12345

调用DaoFactory类中的静态方法getUserDao获取userDao对象,不是由Spring容器负责创建 userDao对象 12 public class DaoFactory{   public IUserDao getUserDao(){   return UserDaoImpl();   } //工厂方法不是静态的 } 12345
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这个数据可以使用Python进行解析和处理。可以按照以下步骤进行: 1. 将数据分割成每个数据项。 ``` data_items = data.split(',') ``` 2. 对于每个数据项,将其按#分割成四个小项,并存储到一个列表中。 ``` data_list = [] for item in data_items: item_list = item.split('#') data_list.append(item_list) ``` 3. 对于每个小项,进行相应的类型转换。 ``` for item in data_list: item[0] = int(item[0]) # 题号转换为整数 item[1] = datetime.datetime.strptime(item[1], '%Y-%m-%d %H:%M:%S') # 时间转换为datetime类型 if item[2] != '': # 操作类型转换为整数 item[2] = int(item[2]) item[3] = str(item[3]) # 科目转换为字符串类型 ``` 4. 可以按照需要对数据进行进一步处理,如按照题号、时间等进行排序、筛选等操作。 完整的Python代码如下: ``` import datetime data = '''1#2021-05-18 14:31:55##初级会计实务,2#2021-05-18 14:31:57#12#初级会计实务,2#2021-05-18 14:32:08##初级会计实务,3#2021-05-18 14:32:09#12#初级会计实务,4#2021-05-18 14:32:34#12#初级会计实务,4#2021-05-18 14:32:45##初级会计实务,5#2021-05-18 14:32:46#12#初级会计实务,5#2021-05-18 14:32:57##初级会计实务,6#2021-05-18 14:33:00#12#初级会计实务,7#2021-05-18 14:33:44#12#初级会计实务,7#2021-05-18 14:34:42##初级会计实务,8#2021-05-18 14:34:43#12''' # 将数据分割成每个数据项 data_items = data.split(',') # 对于每个数据项,将其按#分割成四个小项,并存储到一个列表中 data_list = [] for item in data_items: item_list = item.split('#') data_list.append(item_list) # 对于每个小项,进行相应的类型转换 for item in data_list: item[0] = int(item[0]) # 题号转换为整数 item[1] = datetime.datetime.strptime(item[1], '%Y-%m-%d %H:%M:%S') # 时间转换为datetime类型 if item[2] != '': # 操作类型转换为整数 item[2] = int(item[2]) item[3] = str(item[3]) # 科目转换为字符串类型 print(data_list) ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值