使用Spring进行面向切面编程(AOP)

上传人:gao****ang 文档编号:199063798 上传时间:2023-04-10 格式:DOCX 页数:26 大小:23.18KB
收藏 版权申诉 举报 下载
使用Spring进行面向切面编程(AOP)_第1页
第1页 / 共26页
使用Spring进行面向切面编程(AOP)_第2页
第2页 / 共26页
使用Spring进行面向切面编程(AOP)_第3页
第3页 / 共26页
资源描述:

《使用Spring进行面向切面编程(AOP)》由会员分享,可在线阅读,更多相关《使用Spring进行面向切面编程(AOP)(26页珍藏版)》请在装配图网上搜索。

1、使用Spring进行面向切面编程(AOP )6.1. 简介面向切面编程(AOP )提供另外一种角度来思考程序结构, 通过这种方式弥补了面向对象编程(OOP )的不足。除了 类( classes )以外, AOP 提供了 切面。切面对关注点进行 模块化,例如横切多个类型和对象的事务管理。 (这些关 注点术语通常称作 横切( crosscutting) 关注点。)Spring 的一个关键的组件就是 AOP 框架。 尽管如此, Spring loC容器并不依赖于AOP,这意味着你可以自由选择 是否使用 AOP, AOP 提供强大的中间件解决方案,这使得 Spring loC 容器更加完善。Sprin

2、g 2.0 AOPSpring 2.0 引入了一种更加简单并且更强大的方式来自定 义切面,用户可以选择使用基于模式( schema-based )的 方式或者使用AspectJ注解。这两种风格都完全支持通知 (Advice )类型和AspectJ的切入点语言,虽然实际上仍然 使用 Spring AOP 进行织入( Weaving)。本章主要讨论Spring 2.0对基于模式和基于AspectJ的 AOP支持。请查阅AOP声明风格的选择一节获取 为你的 应用选择适当的声明风格的建议。Spring 2.0完全保留了对 Spring 1.2 的向下兼容性,下一章 将讨论 Spring 1.2 API

3、 所提供的底层的 AOP 支持。Spring中所使用的AOP :提供声明式企业服务,特别是为 了替代 EJB 声明式服务。 最重要的服务是 声明性事务管理 (declarative transaction management) , 这个服务建立 在 Spring 的抽象事务管理(transaction abstraction )之上。允许用户实现自定义的切面,用 AOP 来完善 OOP 的使用。 这样你可以把 Spring AOP 看作是对 Spring 的一种增强,它 使得Spring可以不需要EJB就能提供声明式事务管理;或 者也可以使用 Spring AOP 框架的全部功能来实现自定义

4、的 切面。本章首先 介绍了 AOP 的概念,无论你打算采用哪种风格的 切面声明,这个部分都值得你一读。 本章剩下的部分将着 重于Spring 2.0对AOP的支持;下一章 提供了关于Spring 1.2 风格的 AOP 概述,也许你已经在其他书本,文章以及已 有的应用程序中碰到过这种AOP风格。如果你只打算使用 通用的声明式服务或者预先打包的声明式中间件服务,例如 缓冲池(pooling),那么你不必直接使用Spring AOP,而 本章的大部分内容也可以直接跳过。 6.1.1. AOP 概念 首先让我们从定义一些重要的AOP概念开始。这些术语不 是Spring特有的。不幸的是AOP术语并不是

5、特别的直观; 如果 Spring 使用自己的术语,将会变得更加令人困惑。 切 面(Aspect): 一个关注点的模块化,这个关注点可能会横 切多个对象。事务管理是 J2EE 应用中一个关于横切关注点 的很好的例子。 在 Spring AOP 中,切面可以使用通用类(基 于模式的风格) 或者在普通类中以 Aspect 注解( AspectJ 风格)来实现。连接点( Joinpoint): 在程序执行过程中某个特定的点,比 如某方法调用的时候或者处理异常的时候。 在 Spring AOP 中,一个连接点 总是 代表一个方法的执行。 通过声明一 个 org.aspectj.lang.JoinPoin

6、t 类型的参数可以使通知(Advice )的主体部分获得连接点信息。通知( Advice): 在切面的某个特定的连接点( Joinpoint) 上执行的动作。通知有各种类型其中包括“around”、before” 和“after”等通知。通知的类型将在后面部分进行讨论。许多 AOP框架,包括Spring,都是以拦截器做通知模型,并维 护一个以连接点为中心的拦截器链。切入点(Pointcut):匹配连接点(Joinpoint)的断言。通 知和一个切入点表达式关联,并在满足这个切入点的连接点 上运行(例如,当执行某个特定名称的方法时)。 切入点表 达式如何和连接点匹配是AOP的核心:Spring缺

7、省使用 AspectJ 切入点语法。引入(Introduction ):(也被称为内部类型声明(inter-type declaration)声明额外的方法或者某个类型的字段。 Spring 允许引入新的接口(以及一个对应的实现)到任何被 代理的对象。例如,你可以使用一个引入来使bean实现 IsModified 接口,以便简化缓存机制。目标对象( Target Object): 被一个或者多个切面( aspect) 所通知(advise )的对象。也有人把它叫做被通知(advised) 对象。既然Spring AOP是通过运行时代理实现的,这个对 象永远是一个 被代理( proxied) 对

8、象。AOP代理(AOP Proxy): AOP框架创建的对象,用来实 现切面契约(aspect contract(包括通知方法执行等功能) 在Spring中,AOP代理可以是JDK动态代理或者CGLIB 代理。 注意: Spring 2.0最新引入的基于模式(schema-based)风格和AspectJ注解风格的切面声明, 对于使用这些风格的用户来说,代理的创建是透明的。 织入(Weaving ):把切面(aspect)连接到其它的应用程 序类型或者对象上,并创建一个被通知(advised )的对象。 这些可以在编译时(例如使用 AspectJ 编译器),类加载时 和运行时完成。Spring

9、和其他纯Java AOP框架一样,在 运行时完成织入。通知的类型:前置通知( Before advice): 在某连接点( join point )之前执行的通知,但这个通知不能阻止连接点前的执 行(除非它抛出一个异常)。返回后通知(After returning advice):在某连接点(join point) 正常完成后执行的通知:例如,一个方法没有抛出任何异常, 正常返回。抛出异常后通知( After throwing advice): 在方法抛出异常 退出时执行的通知。后通知( After (finally) advice): 当某连接点退出的时候执 行的通知(不论是正常返回还是异常

10、退出)。环绕通知( Around Advice): 包围一个连接点( join point) 的通知,如方法调用。这是最强大的一种通知类型。 环绕 通知可以在方法调用前后完成自定义的行为。它也会选择是 否继续执行连接点或直接返回它们自己的返回值或抛出异 常来结束执行。环绕通知是最常用的一种通知类型。大部分基于拦截的 AOP 框架,例如Nanning和JBoss4,都只提供环绕通知。跟 AspectJ 一样, Spring 提供所有类型的通知,我们推荐你 使用尽量简单的通知类型来实现需要的功能。 例如,如果 你只是需要用一个方法的返回值来更新缓存,虽然使用环绕 通知也能完成同样的事情, 但是你最

11、好使用 After returning 通知而不是环绕通知。 用最合适的通知类型可以使得编程 模型变得简单,并且能够避免很多潜在的错误。 比如,你 不需要调用 JoinPoint (用于 Around Advice )的 proceed。 方法,就不会有调用的问题。在 Spring 2.0 中,所有的通知参数都是静态类型,因此你可 以使用合适的类型(例如一个方法执行后的返回值类型)作 为通知的参数而不是使用一个对象数组。切入点(pointcut )和连接点(join point)匹配的概念是AOP 的关键,这使得 AOP 不同于其它仅仅提供拦截功能的旧技 术。切入点使得定位通知(advice

12、)可独立于OO层次。例 如,一个提供声明式事务管理的 around 通知可以被应用到 一组横跨多个对象中的方法上(例如服务层的所有业务操 作)。 6.1.2. Spring AOP 的功能和目标Spring AOP 用纯 Java 实现。它不需要专门的编译过程。Spring AOP不需要控制类装载器层次,因此它适用于J2EE web 容器或应用服务器。Spring目前仅支持使用方法调用作为连接点(join point X在 Spring bean 上通知方法的执行)。 虽然可以在不影响到Spring AOP核心API的情况下加入对成员变量拦截器支持, 但Spring并没有实现成员变量拦截器。如

13、果你需要把对成 员变量的访问和更新也作为通知的连接点,可以考虑其它语 法的 Java 语言,例如 AspectJ。Spring 实现 AOP 的方法跟其他的框架不同。 Spring 并不是 要尝试提供最完整的AOP实现(尽管Spring AOP有这个能 力), 相反的,它其实侧重于提供一种 AOP 实现和 Spring IoC 容器的整合,用于帮助解决在企业级开发中的常见问题。 因此,Spring AOP通常都和Spring IoC容器一起使用。Aspect 使用普通的 bean 定义语法(尽管 Spring 提供了强大 的“自动代理(autoproxying ) ”功能):与其他AOP实现相

14、 比这是一个显著的区别。有些事使用Spring AOP是无法轻 松或者高效的完成的,比如说通知一个细粒度的对象。 这 种时候,使用 AspectJ 是最好的选择。不过经验告诉我们: 于大多数在J2EE应用中遇到的问题,只要适合AOP来解 决的, Spring AOP 都没有问题, Spring AOP 提供了一个非 常好的解决方案。Spring AOP从来没有打算通过提供一种全面的AOP解决方 案来取代 AspectJ。 我们相信无论是基于代理(proxy-based )的框架比如说Spring亦或是full-blown的 框架比如说是AspectJ都是很有价值的,他们之间的关系应 该是互补而

15、不是竞争的关系。 Spring 2.0可以无缝的整合 Spring AOP,loC和AspectJ,使得所有的AOP应用完全 融入基于Spring的应用体系。这样的集成不会影响Spring AOP API 或者 AOP Alliance API ; Spring AOP 保留 了向下 兼容性。接下来的一章会详细讨论Spring AOP API。6.1.3. Spring 的 AOP 代理Spring缺省使用J2SE动态代理(dynamic proxies)来作 为 AOP 的代理。这样任何接口都可以被代理。Spring 也支持使用 CGLIB 代理. 对于需要代理类而不是代 理接口的时候CGL

16、IB代理是很有必要的。如果一个业务对 象并没有实现一个接口,默认就会使用 CGLIB。 作为面向 接口编程的最佳实践,业务对象通常都会实现一个或多个接 口。但也有可能会 强制使用 CGLIB, 在这种情况(希望不 常有)下,你可能需要通知一个没有在接口中声明的方法, 或者需要传入一个代理对象给方法作为具体类型在 Spring 2.0之后,Spring可能会提供多种其他类型的AOP代理,包 括了完整的生成类。这不会影响到编程模型。 6.2.AspectJ 支持AspectJ使用了 Java 5的注解,可以将切面声明为普通 的 Java 类。AspectJ 5 发布的 AspectJ projec

17、t 中引入了 这种AspectJ 风格。Spring 2.0 使用了和 AspectJ 5 样 的注解,使用了 AspectJ提供的一个库来做切点(pointcut) 解析和匹配。但是,AOP在运行时仍旧是纯的Spring AOP , 并不依赖于AspectJ的编译器或者织入器(weaver )使 用AspectJ的编译器或者织入器(weaver)的话就可以使用 完整的AspectJ语言,我们将在Section 6.8, “在Spring应 用中使用AspectJ”中讨论这个问题。6.2.1.启用 AspectJ 支持为了在Spring配置中使用AspectJ aspects,你必须首先 启用

18、Spring对基于AspectJ aspects的配置支持,自动代 理(autoproxying )基于通知是否来自这些切面。自动代理 是指Spring会判断一个bean是否使用了一个或多个切面通 知,并据此自动生成相应的代理以拦截其方法调用,并且确 认通知是否如期进行。通过在你的Spring的配置中引入下列元素来启用Spring对 AspectJ的支持:我们假使你正在使用 Appendix A, XML Schema-based configuration所描述的schema支持。关于如何在aop的 命名空间中引入这些标签,请参见 Section A.2.6, “The aop schema

19、”如果你正在使用DTD,你仍旧可以通过在你的application context中添加如下定义来启用AspectJ支持: 你需要在你的应用程序的classpath中引入两个AspectJ库: aspectjweaver.jar 和 aspectjrt.jar。这些库可以在 AspectJ 的安装包(1.5.1或者之后的版本)中的 lib 目录里找到, 或者也可以在Spring依赖库的lib/aspectj目录下找到。6.2.2. 声明一个切面在启用AspectJ支持的情况下,在application context中 定义的任意带有一个Aspect切面(拥有Aspect注解) 的bean都将

20、被Spring自动识别并用于配置在Spring AOP。 以下例子展示了为了完成一个不是非常有用的切面所需要 的最小定义:下面是在application context中的一个常见的bean定义, 这个bean指向一使用了 Aspect注解的bean类: 下面是 NotVeryUsefulAspect 类定义,使用了org.aspectj.lang.annotation.Aspect 注解。 package org.xyz;import org.aspectj.lang.annotation.Aspect;Aspectpublic class NotVeryUsefulAspect 切面(用

21、Aspect 注解的类)和其他类一样有方法和字段 定义。他们也可能包括切入点,通知和引入(inter-type )声 明。 6.2.3. 声明一个切入点( pointcut)回想一下,切入点决定了连接点关注的内容,使得我们可以 控制通知什么时候执行。 Spring AOP 只支持 Spring bean 方法执行连接点。所以你可以把切入点看做是匹配 Spring bean 上方法的执行。 一个切入点声明有两个部分:一个包 含名字和任意参数的签名,还有一个切入点表达式,该表达 式决定了我们关注那个方法的执行。 在 AspectJ 注解风 格的 AOP 中,一个切入点签名通过一个普通的方法定义来

22、提供,并且切入点表达式使用 Pointcut 注解来表示(作 为切入点签名的方法必须返回 void 类型)。 用一个例子会帮助我们区分切入点签名和切入点表达式之 间的差别,下面的例子定义了一个切入点anyOldTransfer, 这个切入点将匹配任何名为 transfer 的方法的执行: Pointcut(execution(* transfer(.)/ the pointcut expressionprivate void anyOldTransfer() / the pointcut signature 切入点表达式,也就是 Pointcut 注解的值,是正规的AspectJ 5 切入点表

23、达式。 如果你想要更多了解 AspectJ 的 切入点语言,请参见 AspectJ 编程指南(如果要了解基于 Java 5 的扩展请参阅 AspectJ 5 开发手册) 或者其他人写 的关于AspectJ的书,例如Colyer et. al.著的Eclipse AspectJ或者 Ramnivas Laddad 著的AspectJ in Action。 6.2.3.1. 切入点指定者的支持Spring AOP 支持在切入点表达式中使用如下的 AspectJ 切 入点指定者:其他的切入点类型完整的 AspectJ 切入点语言支持额外的切入点指定者,但是Spring不支持这个功能。他们分别是cal

24、l, initialization, preinitialization, staticinitialization, get, set, handler, adviceexecution, withincode, cflow, cflowbelow, if, this 和 withincode。在Spring AOP中使用这些指定者将会 导致抛出 IllegalArgumentException 异常。Spring AOP 支持的切入点指定者可能在将来的版本中得到 扩展,不但支持更多的AspectJ切入点指定者(例如if), 还会支持某些Spring特有的切入点指定者,比如bean(用 于匹

25、配bean的名字)execution -匹配方法执行的连接点, 这是你将会用到的Spring的最主要的切入点指定者。within - 限定匹配特定类型的连接点(在使用 Spring AOP 的时候,在匹配的类型中定义的方法的执行)。this -限定匹配特定的连接点(使用Spring AOP的时候方法 的执行),其中 bean reference(Spring AOP 代理)是指定 类型的实例。target - 限定匹配特定的连接点(使用 Spring AOP 的时候方 法的执行),其中目标对象(被代理的 appolication object ) 是指定类型的实例。args - 限定匹配特定的

26、连接点(使用 Spring AOP 的时候方 法的执行),其中参数是指定类型的实例。target - 限定匹配特定的连接点(使用 Spring AOP 的时 候方法的执行),其中执行的对象的类已经有指定类型的注 解。args - 限定匹配特定的连接点(使用 Spring AOP 的时候 方法的执行),其中实际传入参数的运行时类型有指定类型 的注解。within - 限定匹配特定的连接点,其中连接点所在类型已 指定注解(在使用 Spring AOP 的时候,所执行的方法所在 类型已指定注解)。annotation - 限定匹配特定的连接点(使用 Spring AOP 的时候方法的执行),其中连接

27、点的主题有某种给定的注解。因为Spring AOP限制了连接点必须是方法执行级别的, pointcut designators 的讨论也给出了一个定义,这个定义和AspectJ 的编程指南中的定义相比显得更加狭窄。除此之外,AspectJ它本身有基于类型的语义,在执行的连接点this和 target都是指同一个对象,也就是执行方法的对象。Spring AOP 是一个基于代理的系统,并且严格区分代理对象本身(对应于this)和背后的目标对象(对应于target)6232 合并切入点表达式切入点表达式可以使用using &,和!来合并还可以通 过名字来指向切入点表达式。 以下的例子展示了三种切入

28、点表达式:anyPublicOperation (在一个方法执行连接点代 表了任意public方法的执行时匹配);inTrading (在一个代 表了在交易模块中的任意的方法执行时匹配) 和 tradingOperatio(在一个代表了在交易模块中的任意的公共 方法执行时匹配)。 Pointcut(execution(public * *(.) private void anyPublicOperation() Pointcut(within(com.xyz.someapp.trading.*) private void inTrading() Pointcut(anyPublicOperat

29、ion() & inTrading() private void tradingOperation() 就上所示的,从更小的命名组件来构建更加复杂的切入点表 达式是一种最佳实践。 当用名字来指定切入点时使用的是 常见的Java成员可视性访问规则。(比如说,你可以在同 一类型中访问私有的切入点,在继承关系中访问受保护的切 入点,可以在任意地方访问公共切入点。 成员可视性访问 规则不影响到切入点的 匹配。 6.2.3.3. 共享常见的切入点 ( pointcut )定义当开发企业级应用的时候,你通常会想要从几个切面来参考 模块化的应用和特定操作的集合。 我们推荐定义一个 “SystemArchit

30、ecture”切面来捕捉常见的切入点表达式。一个 典型的切面可能看起来像下面这样: package com.xyz.someapp;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Pointcut;Aspect public class SystemArchitecture /* A join point is in the web layer if the method is defined* in a type in the com.xyz.someapp.web package or

31、 any sub-package* under that.*/Pointcut(within(com.xyz.someapp.web.*) public void inWebLayer() /* A join point is in the service layer if the method is defined* in a type in the com.xyz.someapp.service package or any sub-package* under that.*/Pointcut(within(com.xyz.someapp.service.*) public void in

32、ServiceLayer() /* A join point is in the data access layer if the method is defined* in a type in the com.xyz.someapp.dao package or any sub-package* under that.*/Pointcut(within(com.xyz.someapp.dao.*)public void inDataAccessLayer() /* A business service is the execution of any method defined on a s

33、ervice* interface. This definition assumes that interfaces are placed in the* service package, and that implementation types are in sub-packages.* If you group service interfaces by functional area (for example,* in packages com.xyz.someapp.abc.service and com.xyz.def.service) then* the pointcut exp

34、ression execution(* com.xyz.someapp.service.*.*(.)* could be used instead.*/Pointcut(execution(* com.xyz.someapp.service.*.*(.)public void businessService() A data access operation is the execution of anymethod defined on a* dao interface. This definition assumes that interfaces are placed in the* d

35、ao package, and that implementation types are in sub-packages.*/Pointcut(execution(* com.xyz.someapp.dao.*.*(.) public void dataAccessOperation() 示例中的切入点定义了一个你可以在任何需要切入点表达 式的地方可引用的切面。比如,为了使service层事务化, 你可以写成:在 Section 6.3, “Schema-based AOP support” 中讨论 和 标签。在 Chapter 9, 事务管理 中讨论事务标签。 6.2.3.4. 示例Spr

36、ing AOP 用户可能会经常使用 execution pointcut designator。执行表达式的格式如下: execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?) 除了返回类型模式(上面代码片断中的 ret-type-pattern), 名字模式和参数模式以外,所有的部分都是可选的。 返回 类型模式决定了方法的返回类型必须依次匹配一个连接点。 你会使用的最频繁的返回类型模式是 *,它代表了匹配任意 的返回类型。

37、 一个全称限定的类型名将只会匹配返回给定 类型的方法。名字模式匹配的是方法名。 你可以使用 * 通 配符作为所有或者部分命名模式。 参数模式稍微有点复杂: () 匹配了一个不接受任何参数的方法, 而 (.) 匹配了一个 接受任意数量参数的方法(零或者更多)。 模式 (*) 匹配了 一个接受一个任何类型的参数的方法。模式 (*,String) 匹配 了一个接受两个参数的方法,第一个可以是任意类型,第二 个则必须是 String 类型。 请参见 AspectJ 编程指南的 Language Semantics 部分。 下面给出一些常见切入点表达式的例子。任意公共方法的执 行:execution(p

38、ublic * *(.)任何一个以“set”开始的方法的执行:execution(* set*(.)AccountService 接口的任意方法的执行: execution( com.xyz.service.AccountService.*(.)定义在service包里的任意方法的执行:executioncom.xyz.service.*.*(.)定义在service包或者子包里的任意方法的执行:execution com.xyz.service.*.*(.)在service包里的任意连接点(在Spring AOP中只是方法执 行) : within(com.xyz.service.*)在 s

39、ervice 包或者子包里的任意连接点(在 Spring AOP 中只 是方法执行) : within(com.xyz.service.*)实现了 AccountService 接口的代理对象的任意连接点(在 Spring AOP 中只是方法执行) : this(com.xyz.service.AccountService)this在 binding form 中用的更多: - 请常见以下讨论通知的章节中关于如何使得 代理对象可以在通知体内访问到的部分。实现了 AccountService 接口的目标对象的任意连接点(在 Spring AOP 中只是方法执行) :target(com.xyz.

40、service.AccountService)target在 binding form 中用的更多: - 请常见以下讨论通知的章节中关于如何 使得目标对象可以在通知体内访问到的部分。任何一个只接受一个参数,且在运行时传入的参数实现了 Serializable 接口的连接点 (在 Spring AOP 中只是方法执 行)args(java.io.Serializable)args在 binding form 中用的 更多:- 请常见以下讨论通知的章节中关于如何使得方法参 数可以在通知体内访问到的部分。 请注意在例子中给出的切入点不同于 execution(* *(java.io.Serializ

41、able):args 只有在动态运行时候传入参数 是可序列化的(Serializable )才匹配,而execution在传入 参数的签名声明的类型实现了 Serializable 接口时候匹配。有一个 Transactional 注解的目标对象中的任意连接点(在 Spring AOP 中只是方法执行) target(org.springframework.transaction.annotation.Tran sactional)target 也可以在 binding form 中使用:请常见 以下讨论通知的章节中关于如何使得annotation对象可以在 通知体内访问到的部分。任何一个目标对象声明的类型有一个 Transactional 注 解的连接点(在Spring AOP中只是方法执行) within(org.springframework.transaction.annotation.Tran sactional)within也可以在 binding form 中使用:-请常见 以下讨论通知的章节中关于如何

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