




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、杨教授工作室 精心创作的优秀程序员 职业提升必读系列资料第1章 应用层spring框架技术及系统架构(第2/2部分)1.1 spring 框架的系统架构1.1.1 spring 框架的系统架构及主要的组件1、spring 框架的系统架构(1)spring 框架系统在设计方面是采用分层架构设计spring 框架系统不同于j2ee平台中的很多其它的框架实现技术,spring框架并不是一个一体化的整体框架系统,它采用的是分层架构设计和组件化实现。这样将使得使用spring 框架的应用系统的开发者可以根据应用系统中的具体需要从中选取所需要的目标组件,而不必关注其它的组件部分。当然,在实际应用开发中应用
2、的比较频繁的组件则是spring的core部分,也就是ioc的配置框架部分。在应用spring框架的ioc组件时 ,对于基于其上的mvc框架、orm组件以及dao组件等,开发者可以暂时不需要理会它们,但这并不会影响应用系统中对ioc组件的具体应用。(2)spring 框架主要由七个定义良好的各自相互独立的模块组件所构成spring 模块构建在其核心的ioc容器之上,而其核心容器则定义了创建、配置和管理 bean(java中的组件类)的方式,如下图1.2是摘录自spring的技术文档中的系统架构图,在该图中展示了spring框架中七个定义良好的各自相互独立的模块组件。图1.2 摘录自spring
3、的技术文档中的系统架构图2、spring 框架中的七个定义良好的各自相互独立的模块组件的功能说明组成 spring 框架的每个模块(或组件)都可以单独存在,或者与其它的一个或多个模块组件联合使用。根据spring框架中所提供的技术帮助文档,可以了解到每个模块的功能描述如下。 (1)核心容器(spring core)核心容器提供 spring 框架的基本功能。核心容器的主要组件是 beanfactory,它是工厂模式的具体实现。beanfactory 类使用控制反转(ioc)模式将应用程序中所依赖的目标对象与应用程序本身的代码相互分开。(2)spring 上下文(spring context)s
4、pring 上下文是一个配置文件,向 spring 框架提供上下文信息。spring 上下文包括企业服务,例如 jndi、ejb、电子邮件、国际化、校验和调度等方面的功能定义。(3)spring 的面向方面的编程(spring aop)通过配置管理特性,spring aop 模块直接将面向方面的编程功能集成到了 spring 框架中。所以,可以很容易地使 spring 框架管理的任何对象支持 aop技术。spring aop 模块为基于 spring 框架的应用程序中的对象提供了事务管理服务。通过使用 spring aop,可以将声明性事务管理技术集成到应用程序中。(4)spring jdbc
5、 dao 抽象层(spring dao)jdbc dao 抽象层提供了有意义的异常层次结构,可用该结构来管理jdbc api中有关数据库访问操作方面的异常处理和不同数据库供应商抛出的错误消息。异常的层次化结构简化了错误处理,因为spring dao 的面向 jdbc 的异常遵从通用的 dao 异常层次结构。(5)spring orm 的对象关系工具(spring orm)spring 框架提供了对orm对象/关系映射工具的支持,其中包括 jdo、hibernate 和 ibatis sql map等o/r mapping框架的支持;并且利用hibernatedaosupport类可以重用现有的
6、hibernate框架系统。所有对这些o/r mapping框架的支持,都遵从 spring 的通用事务和 dao 异常层次结构。(6)spring web 模块(spring web)web 上下文模块建立在应用程序上下文模块之上,为基于 web 的应用程序提供了上下文。所以,spring 框架支持与 jakarta struts 框架的集成。(7)spring mvc 框架(spring web mvc)spring mvc 框架是一个全功能的构建 web 应用程序的 mvc 实现。通过策略接口,mvc 框架变成为高度可配置的。spring mvc 支持许多视图技术的实现,其中包括 jsp
7、、velocity、tiles、itext 和 poi等。3、spring 框架系统架构的特性体现(1)采用分层架构设计各个部分可以是相互独立的,这正体现了spring框架架构以其灵活性为主要的特点;各个部分相互组合后又能够提供一个全面的企业级的解决方案,从数据访问层到表示层都提供了相应的技术支持。(2)遵守“不重新发明轮子”的理念尽管spring 框架系统本身提供了企业级应用开发中所需要的各个方面的技术的支持,但在全面的技术支持方面的具体的技术实现时则遵守“不重新发明轮子”的理念。比如它也提供了对数据库的数据访问机制的实现,但是它的数据访问机制可以是基于jdbc、hibernate和jdo等
8、不同的实现的,“重用和再包装”的思路充满了整个spring框架中的各个方面的技术实现中。(3)简化j2ee平台中的各种核心和复杂的技术如事务、o/r mapping、aop等的实现在遵守“不重新发明轮子”的理念下,在spring框架中提供了对j2ee平台中各种现有的技术实现的重用和再包装,并通过再包装后为用户提供一个更加简洁和方便的应用接口。比如在spring框架中所提供的jdbctemplate类就是实现对jdbc api 的简化,而提供的hibernatetemplate类也就是实现对hibernate 框架的api 的简化,而提供的transactiontemplate事务模板类则是简化
9、事务编程实现操作。1.1.2 spring 框架主要的技术特性1、spring框架的四大技术特性(1)spring框架采用分层架构设计和实现(2)spring框架是轻量级的j2ee应用开发框架(3)spring框架是一种非侵入式的轻量级框架(4)spring框架是使用控制反转ioc技术的容器2、spring框架采用分层架构(1)分层架构它有七个各自相互独立的模块,这在前面的图1.2中可以了解到。应用系统的开发者可以选择仅仅使用其中的任何一个独立的组件部分。当然,整个spring框架本身也是一个完整的企业级的开发框架。(2)spring框架能够适用于包括j2se和j2ee的各种不同的应用开发环境
10、。这给应用系统的开发者提供了对应用系统及其灵活的开发实现,比如可以采用容器外的开发和实现,包括单元测试技术来简化容器内的项目的开发过程,提高应用系统的开发效率。3、spring框架是轻量级的j2ee应用开发框架(1)什么是轻量级容器组件技术j2ee ejb组件技术是重量级容器的组件技术的典型代表,在重量级容器的组件技术中,组件必须实现某个特定的接口并且必须在某个特定的容器内执行。而轻量级容器的组件技术中的组件可以是简单的java组件类(pojo,plain ordinary java object),并且不依赖于特定的j2ee应用服务器容器的产品。(2)轻量级的j2ee应用开发框架的具体体现l
11、 spring框架使用基本的pojo javabean组件类spring框架使用基本的pojo javabean组件类,并不需要应用系统中的核心组件类必须要实现spring框架中的某个特定的接口或者继承spring框架中的某个基类。l 并且不依赖于j2ee应用服务器容器的产品具体实现从而可以避免像ejb容器那样的重量级实现方案的主要技术缺点,例如启动时间长、测试复杂、部署和配置困难等等。在应用系统的开发中,可以在容器之外进行开发实现,并采用容器外的单元测试技术来进行单元测试以提高开发的效率。不依赖于j2ee应用服务器容器的另外的好处,是能够使应用系统中的核心组件在j2se和j2ee两种不同的运
12、行环境中自由地切换,并提高了系统中组件的可重用度。因此,借助于spring框架后,应用系统的开发者在应用系统中的不同模块或者子系统中可以采用不同的技术实现,同时整个应用系统本身又不依赖于特定的j2ee应用服务器容器环境。4、spring框架是一种非侵入式的轻量级框架(1)“非侵入式”的技术体现允许在应用系统中自由地选择和组装spring框架中的各个功能模块,并且不强制要求应用系统中的类必须从spring框架的系统api中的某个类来继承或者实现某个接口。同时也还提供和其它第三方的框架进行集成的接口,如在spring框架中提供有与hibernate框架、struts框架等的集成的支持。(2)在sp
13、ring框架中是如何达到“非侵入式”的设计目标l 应用java 技术中的反射(reflection)机制为了能够实现无侵入性的目标,在spring框架中大量引入了java 的反射机制,通过动态调用的方式来提供各个方面的功能而避免直接硬编码方式所造成的对应用系统的限制和约束,并在此基础上建立了其核心组件beanfactory,并以此作为其依赖注入机制的技术基础。l 并配合使用spring框架中的beanwrapper和beanfactory组件类最终达到对象的实例创建和属性注入在spring框架中的核心api中的org.springframework.beans包中,定义了这些核心组件的实现类b
14、eanwrapper和beanfactory类。这两个类主要实现对象的创建和属性注入。(3)“非侵入式”的优点允许所开发出的应用系统能够在不同的环境中自由地移植,而不需要修改应用系统中的核心功能实现的代码。注意:当然彻底地“非侵入式”其实也是理想化的!而主要的要求应该是不要在“代码”级特别是应用系统中核心的业务功能类产生侵入(藕合)关系。5、spring框架是使用ioc技术的容器(1)面向接口编程spring框架中提供了管理各种java类对象的一致方法,并且鼓励开发者在编程各个功能类时遵守“面向接口”编程实现类的良好习惯,而不是直接编程目标实现类。(2)为什么要面向接口进行编程实现l 减少系统
15、中的各个组件之间的耦合性减少耦合性后所带来的一个最大好处,就是可以为测试提供更多的方便并且能够简化测试的实现。关于基于spring 框架下的单元测试技术请读者参考本书的第四章中的“对spring框架的单元测试技术”的内容。 l 分离“服务请求者”对“服务提供者”的特定的依赖使得服务请求者无需关心具体的服务实现者的具体实现,纵然实现类发生变化,请求者的调用代码仍然可以不需要修改,这将给系统的维护与功能的扩展带来便利。对此,读者可以参考前面的【例1-13】中所示的代码示例。l 能够更好地遵守面向对象设计中的ocp原则(open-close principle,开放封闭原则)(3)体验理解面向接口编
16、程所带来的减少耦合性的优点因为面向接口编程后,对于调用类来说,不用直接实例化具体的实现类,同时借助java语言中的动态多态性实现对实现类中的方法调用。因此,纵然实现类发生变化,调用者中的代码仍然可以不需要修改。这样将给系统后期的维护与功能的扩展带来更好的灵活性、便利性。前面的【例1-13】中给出的具体的示例,已经就能够说明面向接口编程给应用系统的开发中所带来的减少耦合性的优点。该示例的原理示图请见右面的图1.3所示。图1.3 面向接口编程的原理示图在【例1-13】中所给出的示例中,根据应用系统中的业务功能实现的具体要求,对usermanagerimple类来说daointerface功能接口是
17、固定不变化的,而变化的只是daointerface接口的各个实现类oracledaointerfaceimple和mysqldaointerfaceimple类中的数据访问功能的实现。也就是对功能的扩展是开放的并且是允许的,但不应该直接修改应用系统中的源代码来实现系统的升级和扩展,也就是对修改是封闭的ocp原则;如果应用系统需要应用daointerface接口新的实现类,开发者只需要替换对该实现类的对象创建的实例化的语句或者通过spring的ioc控制反转实现依赖注入,这样对应用系统中的代码修改的工作量是最小的。(4)使用ioc技术同样也能够降低对象之间的耦合度熟悉gof设计模式的读者,已经都
18、习惯于面向接口编程实现(interface driven design),面向接口编程实现有很多优点,比如可以提供不同灵活的实现类,能够增加代码稳定性和健壮性等方面的好处(请见前面的【例1-6】中所示的代码示例)。但是读者也应该知道,接口最终是一定要提供具体的实现类的,也就是如下语句迟早要被应用和执行:daointerface daooperatordbbean=new mysqldaointerfaceimple();其实ioc模式也是分离调用者和被调用者之间的藕合关系的,上面的mysqldaointerfaceimple类对象的实例化的实现语句表明当前是在调用mysqldaointerfa
19、ceimple的实现类中的各个数据访问方法,由于被调用者(也就是目标实现类)名称写入了调用者的代码中,这产生了“彼此关联耦合”,调用者和被调用者有紧密联系。而如果通过ioc技术来实现,则不会出现上面形式的代码。因为,所依赖的目标类的对象实例可以通过ioc容器以属性注入或者构造方法注入的方式来获得。请参考前面的【例1-13】中所给出的示例。(5)使用ioc技术的另一个优点是能工作在一个特定的j2ee应用服务器容器之外可以不依赖一个特定的j2ee应用服务器容器,在j2ee容器之外也能够正常地执行。1.1.3 spring 框架的设计目标1、spring 框架的设计目标是希望能够独立于特定的j2ee
20、应用服务器容器平台(1)可以运行在任何j2ee应用服务器容器中spring 框架中所提供的各个方面的功能可以用在任何 j2ee 应用服务器容器中,并且大多数功能也都适用于不受管理的运行环境。spring框架的核心技术要点是:支持不绑定到特定 j2ee应用服务器容器的可重用业务层和数据访问层的组件对象。(2)最终达到的应用效果这样将可以使应用系统在不同 j2ee 环境 (web运行环境 或者ejb组件的运行环境)、独立的j2se的应用程序环境、单元测试环境等之间进行重用和移植。当然,也就能够简化应用系统的开发、测试等过程。2、spring 2.0 版的ioc容器的xml配置文件笔者在编写本书时,
21、spring的最新版本为spring 2.0 版。根据spring 2.0版中所提供的技术文档了解到,spring 2.0版相当大的改进之一就是spring的ioc容器的xml配置文件。引用新的spring 2.0 dtd以使用基于xml schema的配置,下面为其dtd的定义示例。希望读者注意这些差别,在下面的【例1-14】中给出了一个spring 2.0 版的ioc容器的xml配置文件示例。本书中的所有的示例的xml配置文件都是基于spring 2.0 版的ioc容器的xml配置文件。【例1-14】 spring 2.0 版的ioc容器的xml配置文件示例1.2 体验spring框架中的
22、“依赖注入”的优点1.2.1 在eclipse 中创建基于spring的j2se的应用项目1、在eclipse ide中新建一个j2se 的java项目(project)选择eclipse中的【文件】菜单,再选择【新建】菜单项,并选择【项目】菜单项后;再在对话框中选择java 项目后,点击“下一步”按钮,将看到下面的图1.4中所示的对话框。在该对话框中输入项目的名称为springj2seapp。图1.4 新建java项目对话框2、配置该应用为满足spring框架的要求(1)添加spring的系统库包文件到本项目中的classpath目录中右击项目,在弹出菜单中选择【属性】菜单,将出现下面的图1
23、.5 的项目属性对话框。然后选择【添加外部jar】按钮,将应用spring框架技术时所需要的各种*.jar包的库文件加入到eclipse中的java 构建路径中。图1.5项目属性对话框并添加spring框架的系统包(2)选择所需要的spring框架的*. jar包文件,主要为下面的三个文件1) dist/spring.jar2) lib/jakarta-commons/commons-logging.jar3) lib/log4j/log4j-1.2.9.jar3、添加本项目的spring ioc的配置文件springapplication.xml由于spring框架在管理对象时是依赖于配置文
24、件,因此任何需要交给spring管理的对象,都必须在配置文件中注册和定义。(1)请确保配置文件springapplication.xml位于项目的工作路径中注意在eclipse的ide工具中的项目工作路径并不等同于jvm中的classpath,eclipse的默认工作路径为项目根路径,也就是.project文件所在的目录。可以直接在eclipse中新建出该配置文件springapplication.xml。右击项目,在弹出菜单中选择【新建】菜单,然后再选择【新建文件】菜单项目后,将出现下面的图1.6所示的对话框。在该对话框中输入文件的名称为springapplication.xml。图1.6
25、新建springapplication.xml文件的对话框(2)设计该文件的内容【例1-15】 基于spring 2.0版的ioc的xml配置文件的示例注意:本书中的所有的示例都是基于spring 2.0版的api的,因此ioc的xml配置文件都按照上面的【例1-14】中的格式来实现。4、添加log4j 的属性配置文件perties(1)在spring框架中应用日志管理系统产生工作状态信息spring框架中采用apache common_logging日志管理系统,并结合apache log4j作为日志输出组件。在应用系统的开发过程中,为了在调试过程中能观察到spring的日
26、志输出信息,在应用系统的classpath路径中新建perties属性配置文件。(2)在eclipse中可以新建出该文件选择eclipse中的【文件】菜单,再选择【新建】菜单项,并选择【文件】菜单项后将出现下面的图1.7所示的对话框状态,然后在该对话框中输入文件名称为perties。图1.7 在eclipse中新建perties属性配置文件(3)设计该perties属性配置文件的内容,请见下面的【例1-16】中所示的内容【例1-16】perties属性配置文件的内容示例log4j.rootlogger=i
27、nfo, stdout, logfilelog4j.appender.stdout=org.apache.log4j.consoleappenderlog4j.appender.stdout.layout=org.apache.log4j.patternlayoutlog4j.appender.stdout.layout.conversionpattern=%d %p %c - %nlog4j.appender.logfile=org.apache.log4j.rollingfileappenderlog4j.appender.logfile.file=springapp.loglog4j.a
28、ppender.logfile.maxfilesize=512kb# keep three backup files.log4j.appender.logfile.maxbackupindex=3# pattern to output: date priority category - messagelog4j.appender.logfile.layout=org.apache.log4j.patternlayoutlog4j.appender.logfile.layout.conversionpattern=%d %p %c - %m%n注意:该文件应该放在项目的根目录下,与前面的spri
29、ngapplication.xml文件在同一个目录。另外在利用spring框架进行开发时,如果在控制台上打印输出“log4j:warn please initialize the log4j system properly?”的提示信息,表明在应用系统中没有配置出perties文件或者没有找到该文件。1.2.2 在该j2se项目中添加项目中的各个功能类1、在该项目中再增加一个业务实体类(1)在该项目中增加一个业务实体类userinfovo右击项目名称,选择【新建】菜单,再选择【类】菜单项,将出现下面的图1.5所示的对话框。在对话框的类名称中输入类名称为userinfovo,包
30、名称为 com.px1987.springexample.model。请见下面的图1.8所示的状态。图1.8 增加一个业务实体类userinfovo的对话框(2)在该userinfovo类中新增两个成员属性并为它们提供get/set方法private string username;private string userpassword;请见下面的图1.9中的对话框中的状态显示效果,并通过该业务实体类实现对业务工作参数进行包装。图1.9 为userinfovo类新增两个成员属性的对话框(3)最后eclipse将创建并产生出下面的【例1-17】中所示的代码【例1-17】 eclipse创建出的u
31、serinfovo类的代码示例package com.px1987.springexample.model;public class userinfovo private string username=null;private string userpassword=null;public userinfovo()super();public string getusername() return username;public void setusername(string username) this.username = username;public string getuserpa
32、ssword() return userpassword;public void setuserpassword(string userpassword) this.userpassword = userpassword;2、在该项目中再添加一个业务接口(1)添加一个业务组件的接口右击项目名称,选择【新建】菜单,再选择【接口】菜单项,将出现下面的图1.10所示的对话框。在接口名称的输入框中输入接口名称为userinfointerface,包名称为com.px1987.springexample.model。请见下面的图1.10所示的状态。图1.10 增加一个业务类的接口userinfointe
33、rface的对话框(2)在该接口中添加一个业务方法【例1-18】userinfointerface接口的定义代码示例package com.px1987.springexample.model;public interface userinfointerface public boolean douserlogin(userinfovo oneuserinfo);注意:本示例为了将问题进行简化和节省本书的篇幅,只给出了一个方法的定义。3、在该项目中添加一个业务接口的实现类(1)在该项目中添加一个业务接口的实现类userinfomanage右击项目名称,选择【新建】菜单,再选择【类】菜单项,将出
34、现下面的图1.11所示的对话框。在对话框的类名称中输入类名称为userinfomanage,包名称为 com.px1987.springexample.model,并选择所要实现的接口为前面的userinfointerface接口。请见下面的图1.11所示的状态。图1.11 添加业务接口的实现类userinfomanage的对话框(2)编程userinfomanage类中的功能实现,请见下面的【例1-19】所示【例1-19】userinfomanage类中的功能实现的代码示例package com.px1987.springexample.model;public class userinfo
35、manage implements userinfointerface public userinfomanage() public boolean douserlogin(userinfo oneuserinfo)string username=oneuserinfo.getusername();string useruserpassword=oneuserinfo.getuserpassword();/下面的代码实际应该改变为对数据库的访问boolean okornot=username.equals(yang)&useruserpassword.equals(1234);return o
36、kornot;4、再添加一个测试的应用程序主类usermanagetest(1)在该项目中添加一个测试的应用程序主类usermanagetest右击项目名称,选择【新建】菜单,再选择【类】菜单项,将出现下面的图1.12所示的对话框。在对话框的类名称中输入类名称为usermanagetest,包名称为com.px1987.springexample.test。请见下面的图1.12所示的状态。图1.12 添加一个测试的应用程序主类usermanagetest的对话框(2)编程该usermanagetest类,请见下面的【例1-20】所示【例1-20】usermanagetest类中的代码示例,并注
37、意其中的黑体部分的内容。package com.px1987.springexample.test;import org.springframework.context.applicationcontext;import org.springframework.context.support.filesystemxmlapplicationcontext; import com.px1987.springexample.model.*;public class usermanagetest public usermanagetest() applicationcontext ctx=new f
38、ilesystemxmlapplicationcontext(springapplication.xml);userinfointerface oneuserinfomanage =(userinfointerface) ctx.getbean(oneuserinfomanage);userinfovo oneuserinfo=new userinfovo(); oneuserinfo.setusername(yang);/这些代码模拟用户的表单oneuserinfo.setuserpassword(1234);boolean returnresult=oneuserinfomanage.do
39、userlogin(oneuserinfo);if(returnresult)system.out.println(您登录成功!);elsesystem.out.println(您登录失败!);public static void main(string args)new usermanagetest();注意:正常的应用系统的开发中应该是通过junit的单元测试技术中的测试用例类来实现对目标组件进行单元测试,本示例为了简化和将关注点放在spring 框架的ioc的具体应用方面。读者可以参考本书的第四章中有关基于spring 框架的单元测试技术的内容。5、在前面的springapplicati
40、on.xml文件中添加业务组件类的对象定义修改后的springapplication.xml文件内容的示例请见下面的【例1-21】中的代码示例,并请注意其中的黑体部分的代码内容。【例1-21】 springapplication.xml文件内容的示例 6、执行该测试usermanagetest类的程序(1)启动usermanagetest测试类程序右击usermanagetest测试类程序,在弹出的菜单中选择【运行方式】菜单项目,然后再选择【java应用程序】菜单项目。请见下面的图1.13所示。图1.13 执行usermanagetest类程序(2)将出现下面的执行结果状态,请见下面的图1.14所示。图1.14 执行结果状态显示根据上面的图1.14中所显示的执行结果,表明整个应用系统中的各个类已经被spring框架中的ioc容器所管理,整个实现的程序应该是正确的。(3)再模拟错误登录的状态只需要将测试类中的参数改变为错误的参数(如将图1.14中的setuserpasswor
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- (2025年标准)印刷采购协议书
- 2025年新别墅改造租房协议书
- 2025年新交房装修装饰协议书
- 2025年商事民事仲裁协议书
- 三方债务合同协议书范本
- 水库转包合同协议书模板
- 服装店合作协议合同模板
- 买房赠予协议合同范本
- 楼房过户给孩子的协议书
- 2025年入伙开店合同协议书
- 2024-2025学年华东师大版8年级下册期末试卷附完整答案详解【名校卷】
- 三角形的概念 课件 2025-2026学年人教版(2024)数学八年级上册
- 2025年保密观知识竞赛试题及答案
- 2025年公安机关人民警察招录面试专项练习含答案
- DBJT15-98-2019 建筑施工承插型套扣式钢管脚手架安全技术规程
- 2025年部编版新教材语文七年级上册全套教案设计(含教学设计)
- 医院护理管理课件
- 2025年秋季第一学期开学典礼校长致辞:在历史的坐标上接好时代的接力棒(1945→2025→未来:我们的责任接力)
- 变电运维安全活动个人发言
- 2025年艾梅乙知识竞赛试题及答案
- 消防设施操作员培训模块1 职业道德
评论
0/150
提交评论