黑马程序员spring知识总结 技术帖

上传人:仙*** 文档编号:112910680 上传时间:2022-06-23 格式:DOCX 页数:64 大小:668.33KB
收藏 版权申诉 举报 下载
黑马程序员spring知识总结 技术帖_第1页
第1页 / 共64页
黑马程序员spring知识总结 技术帖_第2页
第2页 / 共64页
黑马程序员spring知识总结 技术帖_第3页
第3页 / 共64页
资源描述:

《黑马程序员spring知识总结 技术帖》由会员分享,可在线阅读,更多相关《黑马程序员spring知识总结 技术帖(64页珍藏版)》请在装配图网上搜索。

1、Spring框架一、技术说明(技术介绍,技术优势以及发展史等)1.1、什么是springl Spring是分层的JavaSE/EE full-stack 轻量级开源框架分层:三层体系结构,为每一个层都提供解决方案web层:struts2、spring-mvcservice层:springdao层:hibernate、mybatis、jdbcTemplate(spring)轻量级:使用时占用资源少,依赖程序少。比较:EJB1.2、spring由来Expert One-to-One J2EE Design and Development ,介绍EJB,使用,特点Expert One-to-One

2、J2EE Development without EJB ,不使用EJB,spring思想1.3、spring核心l 以IoC(Inverse of Control 反转控制)和AOP(Aspect Oriented Programming 面向切面编程为内核)1.4、spring优点l 方便解耦,简化开发 (易扩展,易维护) Spring就是一个大工厂,可以将所有对象创建和依赖关系维护,交给Spring管理l AOP编程的支持 Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能l 声明式事务的支持 只需要通过配置就可以完成对事务的管理,而无需手动编程l 方便程序的

3、测试 Spring对Junit4支持,可以通过注解方便的测试Spring程序l 方便集成各种优秀框架 Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibernate、MyBatis、Quartz等)的直接支持l 降低JavaEE API的使用难度 Spring 对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低1.5、spring体系结构l spring 核心功能:beans、core、context、expression二、环境搭建(技术开发环境)2.1、获取 Spring f

4、ramework jar 包 1、spring官网下载从官网下载spring 最新的相关jar包,官网download地址 http:/www.springsource.org/springcommunity-download 下载完成后会发现三个目录,命名很明确。 Docs 目录相关文档。包括一份 API 和一份各种 spring 的使用说明(reference),reference 提供了 HTML.PDF 版本,非常详细。 2.spring包的核心包 搭建第一个用到 spring 依赖注册的程序 直接用 eclipse 建立一个 JAVA 项目 然后添加 spring 的 jar 包引入

5、 spring-core-3.2.0.M1.jar 核心依赖 jar 包 spring-context-3.2.0.M1.jar Spring 容器包 spring-beans-3.2.0.M1.jar Spring beans 的管理包 spring-asm-3.2.0.M1.jar Spring 注:和 hibernate 一起用时这个 JAR 会冲突,解决方法删掉它就是了 org.springframework.beans.factory.BeanCreationException: Error creating bean with name sessionFactory defined

6、 in ServletContext resource /WEB-INF/classes/applicationContext.xml: Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: org.objectweb.asm.ClassVisitor.visit(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;) Caused by: java.lang.NoSuchMethodEr

7、ror: org.objectweb.asm.ClassVisitor.visit(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)spring-expression-3.2.0.M1.jar 除此之外,还有需要一个 Apache common 的 JAR 包 注:如果忘记添加会 commons-logging-1.1.1.jar 报错Exception in thread main java.lang.NoClassDefFoundError: org/apache/commons/logg

8、ing/LogFactory commons-logging-1.1.1.jar 日志记录 3. 配置 XML Spring 的最大的作用就是提供 bean 的管理功能,在 spring 中 bean 的管理是通过 XML 实现的,要 用此功能,需要把 bean 配置到 spring 的 xml 1. 新建立一个 xml.名字任意,如 applicationContext.xml,或者 text.xml 都可以 2. 添加 xml 头定义 Xmlns(XML NameSpace) 声明命名空间,建议是用网址做命名空间,但并不会去访问改网址, 仅仅是 namespace 和 xsd(xsd 是

9、spring 这个 xml 的 schema 文件,里面定义配置内容)里 声明的 targetNamespace 保持一致 . 注:这里命名空间是改不了的,其实是在代码中也写死了,可以打开 spring-beans3.2.0.M1-sources.jar 包的 orgspringframeworkbeansfactoryxmlBeanDefinitionParserDelegate.java 查看对 http:/www.springframework.org/schema/beans这个namespace的定义。 schemaLoacation .用于绑定命名空间的 schema 文件,通常是

10、用 URL 值对,中间用空格隔 开,前面 URL 是命名空间,后面 URL 为 schema 的文件地址 xsd 的存放地址,如果没有声明,eclipse 会去网上下载. 在创建 xml 时,在 eclipse 编辑 xml 配置没有提示。 可以对 eclipse 中进行 schema 文件的添加 具体是 WindowsPreferences ,搜索 XML catalog,添加 schema 文件。 Spring 的 schema 文件在下载包里有,找到 spring-3.2.0.M1schemabeansspring-beans-3.2.xsd 然后添加,编写 spring 配置文件就能有

11、提示了 4. 依赖注入 4.1 、spring注入的简单案例(入门级)新建一个 class 用于注入, package org.beans; public class Test public void say() System.out.println(welcome); 把类通过 xml 配置注入 测试:package org.beans; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext

12、; public class testBeans public static void main(String args) ApplicationContext ctx = new ClassPathXmlApplicationContext(test.xml); Test test=(Test) ctx.getBean(test); test.say(); 4.2、spring框架为我们提供了三种注入方式,分别是set注入,构造方法注入,接口注入。接口注入不作要求,下面介绍前两种方式。1、set注入 采用属性的set方法进行初始化,就成为set注入。 1)给普通字符类型赋值。javaview

13、 plaincopyprint?1. publicclassUser2. privateStringusername;3. 4. publicStringgetUsername()5. returnusername;6. 7. publicvoidsetUsername(Stringusername)8. this.username=username;9. 10. 我们只需要提供属性的set方法,然后去属性文件中去配置好让框架能够找到applicationContext.xml文件的beans标签。标签beans中添加bean标签,指定id,class值,id值不做要求,class值为对象所在

14、的完整路径。bean标签再添加property 标签,要求,name值与User类中对应的属性名称一致。value值就是我们要给User类中的username属性赋的值。1. 2. 3. 2)给对象赋值同样提供对象的set方法1. publicclassUser2. privateUserServiceuserservice;3. publicUserServicegetUserservice()4. returnuser;5. 6. publicvoidsetUserservice(UserServiceuserservice)7. this.userservice=userservice;

15、8. 9. 配置文件中要增加UserService的bean标签声明及User对象对UserService引用。1. 2. 3. 4. 5. 6. 这样配置,框架就会将UserService对象注入到User类中。 3)给list集合赋值同样提供set方法1. publicclassUser2. privateListusername;3. publicListgetUsername()4. returnusername;5. 6. publicvoidsetUsername(Listusername)7. this.username=username;8. 9. 1. 2. 3. 4. zh

16、ang,san5. lisi6. wangwu7. 8. 9. 4)给属性文件中的字段赋值1. publicclassUser2. privatePropertiesprops;3. publicPropertiesgetProps()4. returnprops;5. 6. publicvoidsetProps(Propertiesprops)7. this.props=props;8. 9. 1. 2. 3. 4. jdbc:oracle:thin:localhost:orl5. oracle.jdbc.driver.OracleDriver6. scott7. tiger8. 9. 10

17、. 标签中的key值是.properties属性文件中的名称注意: 无论给什么赋值,配置文件中标签的name属性值一定是和对象中名称一致。2、构造方法注入 1)构造方法一个参数1. publicclassUser2. privateStringusercode;3. publicUser(Stringusercode)4. this.usercode=usercode;5. 6. 1. 2. 3. 2)构造函数有两个参数时 当参数为非字符串类型时,在配置文件中需要制定类型,如果不指定类型一律按照字符串类型赋值。 当参数类型不一致时,框架是按照字符串的类型进行查找的,因此需要在配置文件中制定是参

18、数的位置1. 2. 3. 这样制定,就是构造函数中,第一个参数为string类型,第二个参数为int类型5、Spring的junit单元测试单元测试以set注入的第一个实例为测试对象。进行单元测试。1,拷贝jar包junit-3.8.2.jar(4.x主要增加注解应用)2,写业务类1. publicclassUser2. privateStringusername;3. 4. publicStringgetUsername()5. returnusername;6. 7. publicvoidsetUsername(Stringusername)8. this.username=usernam

19、e;9. 10. 11. /添加方法12. publicStringlogin()throwsException13. if(admin.equals(username)14. returnsuccess;15. else16. returnerror;17. 18. 19. 3,定义测试类 测试类最好单独建立项目,或者单独定义文件夹存储,需要继承junit.framework.TestCase4,增加测试方法测试方法必须是public,不应该有返回值,方法名必须以test开头,无参数测试方法是有执行先后顺序,按照方法的定义先后顺序多个测试方法对同一个业务方法进行测试,一般每个逻辑分支结构都有

20、测试到。1. publicclassTestUserextendsTestCase2. publicvoidtestUser_Success()throwsException3. /准备数据4. Useraction=newUser();5. action.setUsername(admin);6. 7. /调用被测试方法8. Stringresult=action.login();9. 10. /判断测试是否通过11. assertEquals(success,result);12. 13. 运行程序,如果测试成功会出现如下图所示的结果如果运行失败,有方法没有通过测试,那么就会显示出在哪个方

21、法出错了。上图中绿色的条会变成红色的。5,测试类的生命周期方法1. 2. /用来进行初始化操作3. Override4. protectedvoidsetUp()throwsException5. System.out.println(setUp.);6. 7. 8. /用来做销毁操作9. Override10. protectedvoidtearDown()throwsException11. System.out.println(tearDown.);12. setUp方法会在每一个测试方法前执行一次。tearDown方法会在每一个测试方法后执行一次6、Spring对注解(Annotati

22、on)处理源码分析1扫描和读取Bean定义1、SpringIoC容器对于类级别的注解和类内部的注解分以下两种处理策略:(1).类级别的注解:如Component、Repository、Controller、Service以及JavaEE6的ManagedBean和Named注解,都是添加在类上面的类级别注解,Spring容器根据注解的过滤规则扫描读取注解Bean定义类,并将其注册到Spring IoC容器中。(2).类内部的注解:如Autowire、Value、Resource以及EJB和WebService相关的注解等,都是添加在类内部的字段或者方法上的类内部注解,SpringIoC容器通过

23、Bean后置注解处理器解析Bean内部的注解。下面将根据这两种处理策略,分别分析Spring处理注解相关的源码。2.AnnotationConfigApplicationContext对注解Bean初始化:Spring中,管理注解Bean定义的容器有两个:AnnotationConfigApplicationContext和AnnotationConfigWebApplicationContex。这两个类是专门处理Spring注解方式配置的容器,直接依赖于注解作为容器配置信息来源的IoC容器。AnnotationConfigWebApplicationContext是AnnotationCon

24、figApplicationContext的web版本,两者的用法以及对注解的处理方式几乎没有什么差别,因此本文将以AnnotationConfigApplicationContext为例进行讲解。AnnotationConfigApplicationContext的源码如下:1. publicclassAnnotationConfigApplicationContextextendsGenericApplicationContext2. /创建一个读取注解的Bean定义读取器,并将其设置到容器中3. privatefinalAnnotatedBeanDefinitionReaderreade

25、r=newAnnotatedBeanDefinitionReader(this);4. /创建一个扫描指定类路径中注解Bean定义的扫描器,并将其设置到容器中5. privatefinalClassPathBeanDefinitionScannerscanner=newClassPathBeanDefinitionScanner(this);6. /默认构造函数,初始化一个空容器,容器不包含任何Bean信息,需要在稍后通过调用其register()/方法注册配置类,并调用refresh()方法刷新容器,触发容器对注解Bean的载入、解析和注册过程7. publicAnnotationConfi

26、gApplicationContext()8. 9. /最常用的构造函数,通过将涉及到的配置类传递给该构造函数,以实现将相应配置类中的Bean10. /自动注册到容器中11. publicAnnotationConfigApplicationContext(Class.annotatedClasses)12. register(annotatedClasses);13. refresh();14. 15. /该构造函数会自动扫描以给定的包及其子包下的所有类,并自动识别所有的SpringBean,将其16. /注册到容器中17. publicAnnotationConfigApplication

27、Context(String.basePackages)18. scan(basePackages);19. refresh();20. 21. /为容器的注解Bean读取器和注解Bean扫描器设置Bean名称产生器22. publicvoidsetBeanNameGenerator(BeanNameGeneratorbeanNameGenerator)23. this.reader.setBeanNameGenerator(beanNameGenerator);24. this.scanner.setBeanNameGenerator(beanNameGenerator);25. 26. /

28、为容器的注解Bean读取器和注解Bean扫描器设置作用范围元信息解析器27. publicvoidsetScopeMetadataResolver(ScopeMetadataResolverscopeMetadataResolver)28. this.reader.setScopeMetadataResolver(scopeMetadataResolver);29. this.scanner.setScopeMetadataResolver(scopeMetadataResolver);30. 31. /为容器注册一个要被处理的注解Bean,新注册的Bean,必须手动调用容器的32. /ref

29、resh()方法刷新容器,触发容器对新注册的Bean的处理33. publicvoidregister(Class.annotatedClasses)34. this.reader.register(annotatedClasses);35. 36. /扫描指定包路径及其子包下的注解类,为了使新添加的类被处理,必须手动调用37. /refresh()方法刷新容器38. publicvoidscan(String.basePackages)39. this.scanner.scan(basePackages);40. 41. 通过对AnnotationConfigApplicationConte

30、xt的源码分析,我们了解到Spring对注解的处理分为两种方式:(1).直接将注解Bean注册到容器中:可以在初始化容器时注册;也可以在容器创建之后手动调用注册方法向容器注册,然后通过手动刷新容器,使得容器对注册的注解Bean进行处理。(2).通过扫描指定的包及其子包下的所有类:在初始化注解容器时指定要自动扫描的路径,如果容器创建以后向给定路径动态添加了注解Bean,则需要手动调用容器扫描的方法,然后手动刷新容器,使得容器对所注册的Bean进行处理。接下来,将会对两种处理方式详细分析其实现过程。3.AnnotationConfigApplicationContext注册注解Bean:当创建注解

31、处理容器时,如果传入的初始参数是具体的注解Bean定义类时,注解容器读取并注册。(1).AnnotationConfigApplicationContext通过调用注解Bean定义读取器AnnotatedBeanDefinitionReader的register方法向容器注册指定的注解Bean注解Bean定义读取器向容器注册注解Bean的源码如下:1. /注册多个注解Bean定义类2. publicvoidregister(Class.annotatedClasses)3. for(ClassannotatedClass:annotatedClasses)4. registerBean(ann

32、otatedClass);5. 6. 7. /注册一个注解Bean定义类8. publicvoidregisterBean(ClassannotatedClass)9. registerBean(annotatedClass,null,(Class)null);10. 11. /Bean定义读取器注册注解Bean定义的入口方法12. publicvoidregisterBean(ClassannotatedClass,Class.qualifiers)13. registerBean(annotatedClass,null,qualifiers);14. 15. /Bean定义读取器向容器注册

33、注解Bean定义类16. publicvoidregisterBean(ClassannotatedClass,Stringname,Class.qualifiers)17. /根据指定的注解Bean定义类,创建Spring容器中对注解Bean的封装的数据结构18. AnnotatedGenericBeanDefinitionabd=newAnnotatedGenericBeanDefinition(annotatedClass);19. /解析注解Bean定义的作用域,若Scope(prototype),则Bean为原型类型;20. /若Scope(singleton),则Bean为单态类型

34、21. ScopeMetadatascopeMetadata=this.scopeMetadataResolver.resolveScopeMetadata(abd);22. /为注解Bean定义设置作用域23. abd.setScope(scopeMetadata.getScopeName();24. /为注解Bean定义生成Bean名称25. StringbeanName=(name!=null?name:this.beanNameGenerator.generateBeanName(abd,this.registry);26. /处理注解Bean定义中的通用注解27. Annotatio

35、nConfigUtils.processCommonDefinitionAnnotations(abd);28. /如果在向容器注册注解Bean定义时,使用了额外的限定符注解,则解析限定符注解。29. /主要是配置的关于autowiring自动依赖注入装配的限定条件,即Qualifier30. /注解,Spring自动依赖注入装配默认是按类型装配,如果使用Qualifier则按名称31. if(qualifiers!=null)32. for(Classqualifier:qualifiers)33. /如果配置了Primary注解,设置该Bean为autowiring自动依赖注入装/配时的首

36、选34. if(Primary.class.equals(qualifier)35. abd.setPrimary(true);36. 37. /如果配置了Lazy注解,则设置该Bean为非延迟初始化,如果没有配置,38. /则该Bean为预实例化39. elseif(Lazy.class.equals(qualifier)40. abd.setLazyInit(true);41. 42. /如果使用了除Primary和Lazy以外的其他注解,则为该Bean添加一43. /个autowiring自动依赖注入装配限定符,该Bean在进autowiring44. /自动依赖注入装配时,根据名称装配

37、限定符指定的Bean45. else46. abd.addQualifier(newAutowireCandidateQualifier(qualifier);47. 48. 49. 50. /创建一个指定Bean名称的Bean定义对象,封装注解Bean定义类数据51. BeanDefinitionHolderdefinitionHolder=newBeanDefinitionHolder(abd,beanName);52. /根据注解Bean定义类中配置的作用域,创建相应的代理对象53. definitionHolder=AnnotationConfigUtils.applyScopedPr

38、oxyMode(scopeMetadata,definitionHolder,this.registry);54. /向IoC容器注册注解Bean类定义对象BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder,this.registry);55. (1)从上面的源码我们可以看出,注册注解Bean定义类的基本步骤:a,需要使用注解元数据解析器解析注解Bean中关于作用域的配置。b,使用AnnotationConfigUtils的processCommonDefinitionAnnotations方法处理注解Bean定义

39、类中通用的注解。c,使用AnnotationConfigUtils的applyScopedProxyMode方法创建对于作用域的代理对象。d,通过BeanDefinitionReaderUtils向容器注册Bean。下面我们继续分析这3步的具体实现过程(2).AnnotationScopeMetadataResolver解析作用域元数据:AnnotationScopeMetadataResolver通过processCommonDefinitionAnnotations方法解析注解Bean定义类的作用域元信息,即判断注册的Bean是原生类型(prototype)还是单态(singleton)类

40、型其源码如下:1. /解析注解Bean定义类中的作用域元信息2. publicScopeMetadataresolveScopeMetadata(BeanDefinitiondefinition)3. ScopeMetadatametadata=newScopeMetadata();4. if(definitioninstanceofAnnotatedBeanDefinition)5. AnnotatedBeanDefinitionannDef=(AnnotatedBeanDefinition)definition;6. /从注解Bean定义类的属性中查找属性为”Scope”的值,即Scope

41、注解的值7. /annDef.getMetadata().getAnnotationAttributes方法将Bean8. /中所有的注解和注解的值存放在一个map集合中9. Mapattributes=10. annDef.getMetadata().getAnnotationAttributes(this.scopeAnnotationType.getName();11. /将获取到的Scope注解的值设置到要返回的对象中12. if(attributes!=null)13. metadata.setScopeName(String)attributes.get(value);14. /获

42、取Scope注解中的proxyMode属性值,在创建代理对象时会用到15. ScopedProxyModeproxyMode=(ScopedProxyMode)attributes.get(proxyMode);16. /如果Scope的proxyMode属性值为null、DEFAULT或者NO17. if(proxyMode=null|proxyMode=ScopedProxyMode.DEFAULT)18. /设置proxyMode为NO19. proxyMode=this.defaultProxyMode;20. 21. /为返回的元数据设置proxyMode22. metadata.s

43、etScopedProxyMode(proxyMode);23. 24. 25. /返回解析的作用域元信息对象26. returnmetadata;27. 上述代码中的annDef.getMetadata().getAnnotationAttributes方法就是获取对象中指定类型的注解的值。(3).AnnotationConfigUtils处理注解Bean定义类中的通用注解:AnnotationConfigUtils类的processCommonDefinitionAnnotations在向容器注册Bean之前,首先对注解Bean定义类中的通用Spring注解进行处理源码如下:1. /处理B

44、ean定义中通用注解2. staticvoidprocessCommonDefinitionAnnotations(AnnotatedBeanDefinitionabd)3. /如果Bean定义中有Primary注解,则为该Bean设置为autowiring自动依赖注入/装配的首选对象4. if(abd.getMetadata().isAnnotated(Primary.class.getName()5. abd.setPrimary(true);6. 7. /如果Bean定义中有Lazy注解,则将该Bean预实例化属性设置为lazy注解的值8. if(abd.getMetadata().is

45、Annotated(Lazy.class.getName()9. Booleanvalue=(Boolean)abd.getMetadata().getAnnotationAttributes(Lazy.class.getName().get(value);10. abd.setLazyInit(value);11. 12. /如果Bean定义中有DependsOn注解,则为该Bean设置所依赖的Bean名称,13. /容器将确保在实例化该Bean之前首先实例化所依赖的Bean14. if(abd.getMetadata().isAnnotated(DependsOn.class.getNam

46、e()15. Stringvalue=(String)abd.getMetadata().getAnnotationAttributes(DependsOn.class.getName().get(value);16. abd.setDependsOn(value);17. 18. (4).AnnotationConfigUtils根据注解Bean定义类中配置的作用域为其应用相应的代理策略:AnnotationConfigUtils类的applyScopedProxyMode方法根据注解Bean定义类中配置的作用域Scope注解的值,为Bean定义应用相应的代理模式,主要是在Spring面向切

47、面编程(AOP)中使用源码如下:1. /根据作用域为Bean应用引用的代码模式2. staticBeanDefinitionHolderapplyScopedProxyMode(3. ScopeMetadatametadata,BeanDefinitionHolderdefinition,BeanDefinitionRegistryregistry)4. /获取注解Bean定义类中Scope注解的proxyMode属性值5. ScopedProxyModescopedProxyMode=metadata.getScopedProxyMode();6. /如果配置的Scope注解的proxyMode属性值为NO,则不应用代理模式7. if(scopedProxyMode.equals(ScopedProxyMode.NO)8. returndefinition;9. 10. /获取配置的Scope注解的proxyMode属性值,如果为TARGET_CLASS,则返11. /回true,如果为INTERFACES,则返回false12. booleanproxyTargetClass=scopedProxyMode.equals(ScopedP

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!