Spring知识总结

Spring入门知识详解 Spring 框架是一个轻量级 Java 企业级应用开发框架,其核心设计理念是通过 IoC(控制反转)容器 和 AOP(面向切面编程) 来实现松耦合、高内聚的企业级应用开发。IoC 容器通过依赖注入(DI)机制自动管理对象的创建和依赖关系,开发者只需通过简单的注解(如 @Autowired)即可获取所需依赖,无需手动维护复杂的对象关系;AOP 则通过动态代理技术将横切关注点(如事务管理、日志记录、安全控制等)与业务逻辑分离,使用 @Transactional 等注解就能实现声明式事务管理等高级功能。 阅读详情

 

1.       Spring的技术核心。

      Spring 是一个开源的:控制反转(Inversion of control )IOC ,依赖注入(Dependency Injection )和面向切面(Aop)的框架,它主要的目的是简化企业的开发。

2.       控制反转

所谓控制反转就是:应用本身不负责依赖对象的创建与维护,依赖对象的创建与维护是有外部容器负责的。这样控制权就有应用转向了外部容器,控制权的转移就是所谓的控制反转。

3.       依赖注入

所谓依赖注入就是指: 在运行期 由外部容器动态的将依赖对象注入到组件中。

4.      为什么要使用Spring 呢

    <a>可以降低组件之间的耦合度,实现软件各层之间的解耦;

           Control----àService----àDAO

    <b>使用Spring 容器可以使用它提供的众多服务:事务管理服务,JMS服务,Spring Core服务,持久化服务,其它......

       事务管理: 不需要手工控制事物

    <c>容器提供单利模式支持;

    <d>容器提供了AOP技术,利用它很容易实现如:权限拦截,运行期监控等功能。

    <e>容器提供了很多的辅助类,使用这些类能够加快应用的开发,如: Jdbc Template,

       HibernateTemplate 。

    <f>Spring对主流的应用框架提供了支持如: Hibernate ,JPA , Struts.等。

5.     实例化Spring 容器

两种方式

  A : 在类路径下寻找配置文件来实例化Spring容器。ApplicationContext继承sessionfactory,所以不用sessionfactory

     ApplicationContext ctx = new ClassPathXmlApplicationContext(“config-path”);
     如果是两个以上:
     ApplicationContext ac = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml","dao.xml"});

    或者用通配符:
    ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:/*.xml");

 B:在文件系统路径下寻找配置文件来实例化Spring 容器;

       ApplicationContext ctx = new FileSystemXmlApplicationContext(“d:\\bean.xml”);

       注: 第二种方式通常在本地测试时用,因为每个应用的配置在不同机器上会不同。

       Spring 的配置文件可以通过String 类型的数组配置多个。

       然后就可以通过     

OrderService service = (OrderService)ctx.getBean("personService");

6.      dom4j读解析xml文件

public class ItcastClassPathXmlApplicationContext {

     private List<BeanDefinition> beanDefines = new ArrayList<BeanDefinition>();

     public ItcastApplicationContext(String filename){

        init(filename);

      }  

      private void init(String filename){

       SAXReader saxReader = new SAXReader();  

        Document document=null;  

        try{

         URL xmlpath = this.getClass().getClassLoader().getResource(filename);

         document = saxReader.read(xmlpath);

         Map<String,String> nsMap = new HashMap<String,String>();

         nsMap.put("ns","http://www.springframework.org/schema/beans");//加入命名空间

         XPath xsub = document.createXPath("//ns:beans/ns:bean");//创建beans/bean查询路径

         xsub.setNamespaceURIs(nsMap);//设置命名空间

         List<Element> beans = xsub.selectNodes(document);//获取文档下所有bean节点

         for(Element element: beans){

            String id = element.attributeValue("id");//获取id属性值

            String clazz = element.attributeValue("class"); //获取class属性值       

            BeanDefinition beanDefine = new BeanDefinition(id, clazz);

            beanDefines.add(beanDefine);

         }  

        }catch(Exception e){  

            e.printStackTrace();

        }

    }

7.     Spring配置文件中bean 的属性

Bean 可以有id , name.....   其中id 时唯一的,不可以包含特殊字符。而name可以包含特殊字符。

8.    常用实例化bean的方法

  使用构造方法来实例化bean <bean id=”bean-name” class=”类路径”>通过默认的构造方法来实例化bean对象;

  其它不常用的不介绍

9.   每次通过Spring容器来获得的bean是同一个对象吗
     bean的属性scope=”prototype”,可以让每次实例化的bean对象不同
    默认容器启动就会实例化bean, bean的属性lazy-init=”true”改变这种情况

   进行全局设置:<beans default-lazy-init=”true”>.......</beans>.

10.      Spring中的其它配置

   <bean  init-method=”方法名称”> </bean>这样会在bean实例化之后执行初始化方法。

   既然有初始化方法,那么Spring 也会有销毁的方法。可以这样指定:

  <bean  destroy-method=”方法名”></bean> 

  我们可以通过正常的方式来关闭Spring 容器:

  AbstractApplicationContext  ctx =  new ClassPathXmlApplicationContext();

  Ctx.close(); //关闭容器

11.    Spring中依赖注入的几种方式

基本类型的注入方式:

   <bean id=”bean-name”  class=”classPath”>

       <property  name=”atttibute-name”  value=”value1”></property>//set方式

       <constructor-arg   index=”0”type=”java.lang.String”  value=”xxxxx”>//构造方方式,index=”0”是构造方法的第一个参数,也可以根据type指定参数

</constructor-arg>

</bean>

      注入其它bean:

方式1: 通过属性,设置Setter()方法来注入;这个属性一般式接口形式的。

      <bean id=”bean-name1” class=”classpath”></bean>

      <bean id=”bean-name2” class=”classPath”>

          <property name=”name1” ref=” ”bean-name1”/>//对象的引用

</bean>

方式 2:使用内部bean 但是该bean不能被其它bean使用;

     <bean id=”bean-name1” class=”classpath”></bean>

       <property  name=”name1”>

            <bean  id=”name2” class=”classPath”></bean>//产生一个新的对象

</property>

</bean>

12.   如何为注入集合类型对象(不重要)

Set  List  Map  Peoperty

<bean id=””  ...>

    <property  name=”list”>

     <list>

  <value>1</value>

</lsit>

 </property>

</bean>

set和list没区别

<bean id=””  ...>

    <property  name=”map”>

     <map>

  <entry key="a" value="1"/>

 </map>

 </property>

</bean>

13.  用注解的方式进行依赖注入

需要引入命名空间,和如果要想出现提示信息还要添加schema文件。在上图中有详细的说明。

14.     在spring中使用注解进行IOC

 

然后在bean.xml中写入

<aop:aspectj-autoproxy/> <!—和建立代理有关-->

15.    注入方式

@Autowired:默认是byType,配合Qualifier可以指定name

@Resource:默认byName,找不到byType

@resource需要导入spring->lib->j2ee->common-annotaion.jar

异常处理一般在struts这层处理,spring很少处理异常

  指定默认扫描方式:
<benan id=”bean-name” class=”class-path” autowire=”default”>

autowire取值如下:byType; byName; constructor; Autaodetect 16.通过classpath自动扫描的方式把组件注入到spring容器中管理;

注册解析注解的解析器;

<context:annotation-config />

注册注解的解析器同样也包括上面的范围,故有下面的配置时上面的配置可以不要;

 <context:component-scan base-package="wto.bean" />

这种方法也可以通过注解来设定初始化方法,销毁方法,也可以指定bean的名称。

 @Servic 业务层组件

 @Controller 控制层组件

 @Repositiory  数据访问层组件 以上三种组件目前还没有区别可以随便用。

 @Component 泛指组件 当组件不好归类的时候我们可以使用这个注解进行标注。

 @Scope 设置bean的模式是(单利)single 还是proptoto(原型)

以上注解都是标注在类上的

下面的注解是标注在方法上的:

 @PostConstruct   设定初始化方法

 @PreDestroy       设定销毁的方法

16. 在spring中使用AOP(面向切面编程)

 动态代理:被代理对象要组合到代理类.代理类要实现invacationhandler.  用proxy.newInstance()返回的对象.但是hibernate中的动态代理是直接操作的二级制码,spring也类似,所以需要引入cglib相关包

17.AOP中的一些概念:Aspect(切面),joinpoint(连接点),Pointcut(切入点)Advicce(通知)Target(目标对象),Weave(织入),Introduction(引入)

18.基于注解方式声明切面,但是AOP用xml好,IOC用annotation好

19.Spring对数据库的支持

 hibernate对数据库的支持DPCP,需要导入common-dbcp.jar;common-pool.jar

<bean id=" myDateSource >

  class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">

  <property name="dirverClassName" value="com.mysql.jdbc.Driver"/>

  <property name="url" value="jdbc:mysql://localhost:3306/spring/>

  <property name="username" value="root"/>

  <property name="password" value="root"/>

</bean>

<bean id="mySessionFactory" class="org.springframework.orm.hibernate3. AnnotationSessionFactoryBean >

<--用注解必须是这个接口而不是LocalSessionFactory-->

 <property name="dateSource ref="myDateSource"/>

 <property name="mappingResources">

 <list>

  <value>product.hbm.xml</value>

</list>

<property name="hibernateProperties>

  <value>

     hibernate.dialect=org.hibernate.dialect.HSQLDialect

  </value>

</property>

 

</bean>

 

可以用占位符和property文件配合使用

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

 <property name="locations">

   <value>classpath:jdbc.perperties</value>

 </property>

</bean>

<bean id="dateSource" destroy-mothod="close">

 <property name="dirverClassName" value="${jdbc.driverClassName}/>

 <property name="url" value="${jdbc.url}/>

 <property name="username" value="${jdbc.username}/>

 <property name="password" value="${jdbc.password}/>

</bean>

jdbc.properties

jdbc.driverClassName=com.mysql.jdbc.Driver

jdbc.url=jdbc:mysql://localhost:3306/spring

jdbc.username=root

jdbc.password=root

JDBC+spring整合开发的时候就可以用其实还可以,用如下的方法

<bean id="txtManager" class="org.springframework.jdbc.datesource.DateSourceTransactionManager>

 <property name="dateSource" ref="dateSource"/>

</bean>

补充:属性文件还可以用下面方式赋值

<property name="adminEmails">

  <props>

    <prop key"adminstrator">adminstrator@example.org</prop>

    <prop key="support"> support@example</prop>

  </props>

</property>

20 .  Spring支持事务管理

首先修改配置,和加入相应的schema

<tx:annotaion-driven transaction-manager="txtManager">

<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTrasactionManager>

 <property name="sessionFatory ref="sessionFactory"/>

</bean>

使用@Transactional

@Transactional

public void add(User user){

  userDAO.save(user);

  Log log = new Log();

  Log.setMsg("a user saved!");

  LogDAO.save(log);

}

现在假如手动throw new RuntimeException("testerror");事务就会回滚了

propagation:是衍生,繁殖,就是事务的传播方式;

默认是REQUESTED,还有其他值,这个做了解
MANDTROY,NESTED,NEVER,NOT_SUPPORTED,REQUESTES_NEW,SUPPORTS

 

花了14天做了一张spring脑图,所有spring知识点都汇总了!2020最新Spring全家桶高频面试题 花了14天做了一张spring脑图,所有spring知识点都汇总了!2020最新Spring全家桶高频面试题,现在分享给大家。spring知识脑图放在文末。 对于那些想面试高级 Java 岗位的同学来说,spring是一大绕不过的坎!剩下针对实际工作的题目就属于真正的本事了,热门技术的细节和难点成为了面试时主要考察的内容。 这里总结了 70 道 Spring 相关面试题,有的很基础,有的很细节,大家可以评估一下自己掌握的情况。 这里把重要的知识点都写出来了,不管是核心知识点也好还是面试题也好,让大家对知识框 阅读详情

相关推荐

这30个Spring Boot知识点,你很有必要学一下

前言 Spring Boot 是一套快速开发框架,随着微服务架构应用不断普及,Spring Boot的研发技术的掌握已经成为研发人员必会技能。 与此同时,Spring Boot 开源生态建设能力非常强大,提供了很多应用组件,让Spring Boot 有丰富的三方开源软件的使用。 基于上面的情况,Spring Boot ...

豆汁 1683

Spring Boot 中 @Repository 注解全析

这意味着不需要在 XML 或显式的配置中声明这个 Bean,只要类在被扫描的包路径下,Spring Boot 就会自动将其注册到容器中。是 Spring 提供的一个数据访问层(DAO,Data Access Object)标识注解,用于标记存储、检索、搜索、更新和删除数据的类。首先,它明确了当前类的角色是持久层组件,增强代码语义,让团队成员一目了然地知道该类负责数据操作。的类会被 Spring 自动纳入异常翻译机制,使得底层异常不会泄漏到上层,而是以一致的异常类型出现。或其子类,然后再抛出。

m0_73464010的博客 2560

TwinCAT3 实时核异步通信:基于ADS的C++ Server/Client数据交换实战解析

本文深入解析了在TwinCAT3实时核中,如何利用ADS协议实现C++ Server与Client之间的异步数据交换。文章从核心概念入手,详细阐述了实时核、ADS通信及异步机制,并通过实战步骤指导环境搭建、路由配置、Server端服务创建与Client端请求发起,重点剖析了Req/Ind/Res/Con异步回调模型,旨在帮助开发者构建高效、非阻塞的实时工业控制应用。

purple的博客 469

@Repository的作用?

Spring的注解形式:@Repository、@Service、@Controller,它们分别对应存储层Bean,业务层Bean,和展示层Bean。@Repository、@Service、@Controller 和 @Component 将类标识为BeanSpring 自 2.0 版本开始,陆续引入了一些注解用于简化 Spring 的开发。@Repository注解便属于最先引入的一批,它用...

qq_40943786的博客 16万+

避坑指南:Qt5.14.2 ARM交叉编译中那些你可能遇到的‘坑’及解决方案

本文深度解析了Qt 5.14.2在ARM架构上进行交叉编译的完整流程与常见难题。重点阐述了如何精准匹配交叉编译器与目标板环境、正确配置sysroot以及使用configure参数的艺术,并针对编译过程中的头文件缺失、链接错误等典型“坑”提供了经过验证的解决方案,旨在帮助开发者成功构建适用于嵌入式设备的Qt运行时库。

weixin_29279101的博客 355

逻辑漏洞:水平越权、垂直越权靶场练习

水平越权和垂直越权是组织中常见的管理问题,指的是员工在组织中所拥有的权力和责任超出其职位所应具备的范围。 水平越权是指员工在同一级别的职位上超越了其同事的权力和责任范围,通常表现为某个员工在团队中承担了过多的任务或权力,导致其他同事感到不公平或不满。 垂直越权则是指员工在组织中超越了其职位等级的权力和责任范围,通常表现为员工在没有得到上级批准的情况下做出决策或行动,可能会导致组织内部的混乱和冲突。

qq_68163788的博客 2472

开发资源库(repositiory)

1.. 52研发网MTK软件 2.一流研发   3. android+MTK/华为的源代码及资料库(CryToCry96) 点击打开链接   4.android+MTK/华为/联想的源代码及资料库(luckasfb) 点击打开链接   5.MTK官网 点击打开链接   6.AndroidPolice:安卓手机系统开源资讯博客 AndroidPolice:安卓手机系统开源资...

LoongEmbedded的专栏 3437

ParallelsDesktop 安装 CentOS-6.9-x86_64-minimal 教程

安装参考 tools没做 想安装的可以参考这个 mac 本机环境: 系统:macOS Catalina version 10.15.6 虚拟机软件:parallels Desktop 15 for Mac( Parallels Desktop-15.1.4(47270)) Centos镜像: CentOS-6.9-x86_64-minimal.iso https://mirrors.aliyun.com/centos-vault/6.8/isos/x86_64/ http://vault.centos.

爱吃鱼的小明的博客 955

Spring知识框架

Spring知识框架 Spring总体架构 IOC知识体系图

CyberXavier的博客 278

地图自定义编码CSV转换成ini文件

创 建 schema.ini 文件:有时,当您尝试使用 .csv 文件将自定义地理信息导入 Tableau 时,您可能会看到“无法使用.csv,因为它不包含唯一列”错误消息。这是因为您的 .csv 文件可能包含数值数据,例如数值邮政编码。对于新的地理角色,Tableau 将只接受文本字段。但是,您可以创建一个 schema.ini 文件,以指示 Tableau 应将您要导入的数值字段视为文本字段。...

wenyusuran的专栏 1975

【微服务】Java 对接飞书多维表格使用详解

Java 对接飞书多维表格使用详解

congge_study的博客 1万+

spring相关知识

Spring 是 Java 生态系统中最流行的框架之一,提供了丰富的功能和模块,用于构建企业级应用。以下是 Spring、Spring Boot、Spring MVC 和 Spring Cloud 的知识汇总,涵盖了它们的基本概念、核心特性、使用场景和常见问题。Spring 提供了多个扩展点,允许开发者在 Bean 的生命周期中插入自定义逻辑。Spring 生命周期是指 Spring 容器管理 Bean 的创建、初始化、使用和销毁的过程。其中Bean 的实例化、属性赋值、初始化、使用和销毁为核心阶段。

blue_msboy的博客 1141

基于VLFM的中文指令视觉语言导航系统设计与实现

文章摘要 本文介绍了一个基于VLFM(视觉语言边界地图)的中文指令视觉语言导航系统设计与实现。该系统采用模块化架构,包含三维场景渲染、URDF机器人仿真、VLFM导航引擎、中文指令解析和PyQt图形界面五大核心模块。系统支持自定义GLB场景模型和URDF机器人模型,通过transformers和langchain实现中文自然语言指令解析,利用VLFM算法进行语义导航决策。技术实现上详细介绍了GLB模型加载器开发、URDF机器人控制、VLFM导航算法集成以及PyQt界面设计。该系统在Ubuntu环境下运行,依

AI的内部世界的博客 211

Spring Boot 使用 Spring AI 构建知识库服务

做 AI 大模型技术调研时,参考的开源项目 Maxkb,它基于大模型做了一个的应用,用户可构建自己的知识库,创建自己的应用然后关联知识库,这样可以基于知识库里的内容让大模型的回答更加符合我们地预期。虽然 Maxkb 是使用 Python 写的,不过参考它用到的相关模型和数据库,可以用 Spring Boot 来构建一个自己的知识库服务。Spring Boot 也提供了 AI 相关的库,这使得接入 AI 大模型能力也十分方便。以下是使用Spring Boot 构建一个知识库的样例。

6559

汽车电子RTOS--AUTOSAR OS

AUTOSAR OS(AUTomotive Open System ARchitecture Operating System)是AUTOSAR(汽车开放系统架构)标准中的一个重要组件,它是一个专门为汽车电子控制单元(ECU)设计的实时操作系统(RTOS)。AUTOSAR OS旨在提供一个标准化的软件平台,以促进不同供应商和汽车制造商之间的组件复用和协同开发,提高软件质量和降低成本。

MHD0815的博客 1800

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

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

Spring知识

Spring知识图谱

后山de小猿 202

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Spring知识点梳理

AOP切面编程:类似于一种拦截器,像一把刀一样选择一个方法为切入点,在这个方法执行的前后可以设置前置通知、后置通知、异常通知等,这些通知可以是对业务进行判断、日志记录、事务回滚等操作。CGLIB 就是第三方 Jar 包,它的作用是在程序运行时,动态生成新的 Java 类(目标类的子类),从而实现代理功能(比如在不修改原有代码的情况下,给某个类的方法增加额外逻辑,如日志、事务、权限控制等)。</</</</Bean就是Spring框架帮忙创建和管理的“对象镜像”、“clazz对象”,即代理对象;

410的博客 1439

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Spring知识点

Spring知识点

YIYIYI 1580

【Spring】RAG 知识库基础

详细介绍了RAG相关概念以及通过SpringAI、SpringAi Alibaba框架实现本地知识库与云知识库RAG实战功能

weixin_62533201的博客 1751

Spring AI 基于 RAG 构建本地知识库问答助手

Spring AI 提供了对 RAG(检索增强生成)的支持,通过向量检索增强技术,将本地私有化知识内容嵌入并存储到向量库中,作为知识库。当用户提问时,通过向量相似度检索召回相关知识,并将其作为上下文背景组装到 Prompt 中,从而增强大模型对私有知识的感知能力,减少幻觉。Spring AI 提供了多种文档读取器(如 JSON、PDF、Markdown 等)和文本拆分工具,并支持多种向量库。本文介绍了如何在 Spring Boot 项目中搭建 RAG 流程,使用 OpenAI 的 GPT-4.1 和 tex

小毕超博客 1378

来吧!你要的spring+spring5知识梳理大纲已绘好.

来吧来吧!熬了整整一周,重要手绘好最全spring+spring5的知识梳理大纲! 请注意:手绘图为xmind文件,在文章中是无法上传的,因此全部以截图方式展示出来,不过小编这都有完整的手稿原件,原件更加清晰明了(内容非常多),想看手稿原件在这里 spring+spring5最全知识梳理大纲(总) spring最全知识梳理大纲(总) spring5最全知识梳理大纲(总) spring最全知识梳理大纲(分) 为什么要使用Spring? ...

mifffy_java的博客 321

spring的冷门知识

spring的冷门知识储蓄

weixin_44962939的博客 162

Spring Boot核心知识清单

Spring Boot核心知识清单Spring Boot核心知识清单Spring Boot核心知识清单Spring Boot核心知识清单

weixin_49376454的博客 1309

spring高级知识概览

​:Spring Cloud Gateway 的路由规则、限流熔断(结合 Resilience4j),以及 OpenAPI 3.0 自动化文档生成。​:Eureka 注册中心的高可用配置,Nacos 的动态配置管理,以及 Consul 的服务发现机制。​:自定义认证流程(如多因素认证),JWT 的签名算法选择(HS256 vs RS256)。​:统一模型抽象接口(如 OpenAI、通义千问),流式响应(SSE)实现逐词输出。​:SonarQube 静态扫描代码异味,Checkstyle 统一编码规范。

2402_83164836的博客 720

Spring知识点总结

Spring AOP 什么是AOP AOP,其实就是面向切面编程,将一些公共逻辑(事务管理、日志、缓存等)封装成切面,跟业务代码进行分离,可以减少系统的重复代码和降低模块之间的耦合度。切面就是那些与业务无关,但所有业务模块都会调用的公共逻辑。 动态代理的实现方式有哪些 动态代理技术的实现方式有两种: 基于接口的 JDK 动态代理。 基于继承的 CGLib 动态代理。在Spring中,如果目标类没有实现接口,那么Spring AOP会选择使用CGLIB来动态代理目标类。 CGlib动态代理 C

正在努力工作的搬砖人 1103
上一篇: Hibernate知识总结
下一篇: SSH2整合入门
billycoder
博客等级 码龄17年 171粉丝 188原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值