知识大全 Groovy使Spring更出色,第1 部分: 集成的基础知识
Posted 知
篇首语:智者不为愚者谋,勇者不为怯者死。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 Groovy使Spring更出色,第1 部分: 集成的基础知识相关的知识,希望对你有一定的参考价值。
Groovy使Spring更出色,第1 部分: 集成的基础知识 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
Spring Framework 为 Web 和企业应用程序提供了坚实的基础 通过支持 Groovy 等动态语言 Spring 添加了一些功能 从而使应用程序架构更加灵活 更具动态性 在包含 部分的系列文章 的第一部分中 您将学习将 Groovy 集成到 Spring 应用程序的基础知识
Spring 支持将动态语言集成到基于 Spring 的应用程序中 Spring 开箱即用地支持 Groovy JRuby 和 BeanShell 以 Groovy JRuby 或任何受支持的语言(当然包括 Java? 语言)编写的应用程序部分可以无缝地集成到 Spring 应用程序中 应用程序其他部分的代码不需要知道或关心单个 Spring bean 的实现语言
Spring 支持动态语言意味着应用程序可以获得灵活性和动态性 并且没有任何附加条件 在本系列的第 部分中 您将看到如何将 Spring 和 Groovy 一起使用 以及这个强大集成如何为应用程序增加有趣的功能 例如 您可能需要频繁地更改小块的业务逻辑 应用程序发出的 e mail 消息中包含的文本 应用程序生成的 PDF 格式和布局等 为了进行更改 传统的应用程序架构可能需要完全重新部署应用程序 Spring 支持 Groovy 之后 您可以这样更改一个已部署的应用程序 并使这些更改立即生效 我将讨论这一功能为应用程序所带来的好处 以及可能引发的问题 本文中所有例子的完整的源代码(参见 下载)都可以下载
Spring 的动态语言支持
动态语言支持将 Spring 从一个以 Java 为中心的应用程序框架改变成一个以 JVM 为中心的应用程序框架 现在 Spring 不再只是让 Java 开发变得更容易 它还允许将以静态和动态语言编写的代码轻松地插入到 Spring 支持的分层架构方法中 从而使 JVM 的开发也变得更加容易 如果您已经熟悉 Spring 那么您会感到很舒服 可以利用 Spring 已经提供的所有特性 — 控制反转(IoC)和依赖项注入 面向方面编程(AOP) 声明式事务划分 Web 和数据访问框架集成 远程调用等 — 同时又可以使用灵活动态的语言 比如 Groovy
Spring 通过 ScriptFactory 和 ScriptSource 接口支持动态语言集成 ScriptFactory 接口定义用于创建和配置脚本 Spring bean 的机制 理论上 所有在 JVM 上运行语言都受支持 因此可以选择特定的语言来创建自己的实现 ScriptSource 定义 Spring 如何访问实际的脚本源代码 例如 通过文件系统或 URL Groovy 语言集成通过 ScriptFactory 的 GroovyScriptFactory 实现得到支持
为什么是 Groovy?
根据官方的 Groovy 站点 Groovy 是 用于 Java 虚拟机的一种敏捷的动态语言 它 以 Java 的强大功能为基础 同时又包含由 Python Ruby 和 Smalltalk 等语言带来的强大附加功能 例如动态类型转换 闭包和元编程(metaprogramming)支持(参见 参考资料) 它是一种成熟的面向对象编程语言 既可以用于面向对象编程 又可以用作纯粹的脚本语言 我喜欢将它看作是没有讨厌代码 但又具有闭包和动态语言中的其他特性的 Java 语言
Groovy 特别适合与 Spring 的动态语言支持一起使用 因为它是专门为 JVM 设计的 设计时充分考虑了 Java 集成 这使 Groovy 与 Java 代码的互操作很容易 它的类 Java 语法对于 Java 开发人员来说也很自然
接下来 看看如何将 Groovy 代码集成到基于 Spring 的应用程序中
更巧妙的 Spring bean
在 Spring 应用程序中使用 Groovy bean 很容易 就像使用 Java bean 一样 (但是 在后面可以看到 对于如何配置它们 则有很多选项) 首先 需要定义一个接口作为 Groovy bean 必须遵从的约定 虽然不是非得定义接口不可 但是大多数 Spring 应用程序会通过接口(而不是具体实现类)来定义应用程序组件之间的交互和依赖项 以促进松散耦合并为测试提供便利
例如 假设有一个定义如何从 Invoice 对象生成 PDF 的接口 如清单 所示
清单 PdfGenerator 接口
public interface PdfGenerator byte[] pdfFor(Invoice invoice);
PdfGenerator 接口被用作 Groovy 实现类必须遵从的约定 这很容易 因为 Groovy 类可以像 Java 类那样实现接口 清单 显示了 PdfGenerator 的 Groovy 实现 它使用 iText 库(参见 参考资料)完成实际的 PDF 生成 它返回一个包含 PDF 内容的字节数组
清单 GroovyPdfGenerator
class GroovyPdfGenerator implements PdfGenerator String panyName public byte[] pdfFor(Invoice invoice) Document document = new Document(PageSize LETTER) ByteArrayOutputStream output = new ByteArrayOutputStream() PdfWriter getInstance(document output) document open() Font headerFont = new Font(family: Font HELVETICA size: style: Font ITALIC) document add(new Paragraph( $panyName headerFont)) document add(new Paragraph( Invoice $invoice orderNumber )) document add(new Paragraph( Total amount: \\$ $invoice total )) document close() output toByteArray()
GroovyPdfGenerator 已准备就绪 它定义了一个名为 panyName 的 string 属性 该属性在生成的 PDF 发票上与订单号和总额一起使用 此时 可以将 GroovyPdfGenerator 集成到 Spring 应用程序中 使用 Java 语言编写的 bean 必须编译成 class 文件 但是在使用基于 Groovy 的 bean 时 则有几种选择
将 Groovy 类编译成普通的 Java 类文件
在一个 groovy 文件中定义 Groovy 类或脚本
在 Spring 配置文件中以内联方式编写 Groovy 脚本
可以选择不同的方法在 Spring 应用程序上下文中定义和配置 Groovy bean 这取决于 Groovy bean 采用的选项 接下来 我们将探讨每一种配置选项
Groovy bean 配置
通常 可以使用 XML 配置用 Java 代码编写的 Spring bean 或者 — 从 Spring (参见 参考资料)开始 — 使用注释进行配置 后者可以显著减少 XML 配置 当配置 Groovy bean 时 可用的选项取决于是使用编译的 Groovy 类还是 groovy 文件中定义的 Groovy 类 需要记住的是 您可以使用 Groovy 实现 bean 然后可以像 Java 编程那样编译它们 或者在 groovy 文件中以类似脚本的形式实现它们 然后由 Spring 负责在创建应用程序上下文时编译它们
如果选择在 groovy 文件中实现 bean 那么您不必 自己编译它们 相反 Spring 读取文件 获得脚本源代码并在运行时编译它们 使它们可用于应用程序上下文 这比直接编译更灵活性 因为不一定必须将 groovy 文件部署在应用程序的 JAR 或 WAR 文件中 它们还可以来自文件系统的某个地方或 URL
接下来介绍各种不同的配置选项的应用 要记住在构建过程中自己编译的 Groovy 类中定义的 bean 与在 groovy 脚本中定义的 bean 之间的区别
配置编译的 Groovy 类
配置已经编译成 class 文件的 Groovy bean 这与配置基于 Java 的 bean 完全一样 假设您已经使用 groovyc 编译器编译了 GroovyPdfGenerator 那么可以使用常规的 Spring XML 配置定义 bean 如清单 所示
清单 使用 XML 配置预编译的 GroovyPdfGenerator
<bean id= pdfGenerator class= groovierspring GroovyPdfGenerator > <property name= panyName value= Groovy Bookstore /></bean>
清单 中的配置是一个简单的旧的 Spring bean 定义 它是用 Groovy 实现的 但这一点不重要 在包含 pdfGenerator bean 的 Spring 应用程序中 任何其他组件都可以使用它 而不必知道或关心它的实现细节或语言 还可以像往常一样使用 <property> 元素在 bean 上设置属性 (Spring 引入了 p 名称空间 以便更简练地定义属性 但是我坚持使用 <property> 元素 因为我发现它们可读性更好 — 这完全是个人的喜好)
另外 如果使用 Spring 或更高版本 还可以使用基于注释的 GroovyPdfGenerator 的配置 在此情况下 不必在 XML 应用程序上下文中实际定义 bean 相反 可以用 @Component 构造型注释来注释类 如清单 所示
清单 用 @Component 注释 GroovyPdfGenerator
@Component( pdfGenerator )class GroovyPdfGenerator implements PdfGenerator
然后 在 Spring 应用程序上下文 XML 配置中启用注释配置和组件扫描 如清单 所示
清单 启用 Spring 注释配置和组件扫描
<context:annotation config/><context:ponent scan base package= groovierspring />
不管使用 XML 还是注释来配置编译后的 Groovy bean 这种配置与普通的基于 Java bean 的配置是一样的
配置来自 Groovy 脚本的 bean
配置来自 groovy 脚本的 Groovy bean 与配置编译后的 Groovy bean 大不相同 在这里 事情开始变得更加有趣 将 Groovy 脚本转换为 bean 的机制包括读取并编译 Groovy 脚本 然后使之可以在 Spring 应用程序上下文中作为 bean 使用 第一步是定义一个 bean 它的类型可以认为是 GroovyScriptFactory 并且指向 Groovy 脚本的位置 如清单 所示
清单 定义 GroovyScriptFactory bean
<bean id= pdfGenerator class= springframework scripting groovy GroovyScriptFactory > <constructor arg value= classpath:groovierspring/GroovyPdfGenerator groovy /> <property name= panyName value= Groovier Bookstore /></bean>
在这个清单中 pdfGenerator bean 被定义为 GroovyScriptFactory <constructor arg> 元素定义要配置的 Groovy 脚本的位置 特别要注意 这指向一个 Groovy 脚本 而不是一个已编译的 Groovy 类 可以使用定义 Spring bean 的语法设置用脚本编写的对象的属性 正如您预期的那样 清单 中的 <property> 元素设置 panyName 属性
GroovyPdfGenerator groovy 脚本 必须包含至少一个实现接口的类 通常 最好的做法是遵从标准 Java 实现 每个 groovy 文件定义一个 Groovy 类 但是 您可能想在脚本中实现用于确定创建哪种类型的 bean 的逻辑 例如 可以在 GroovyPdfGenerator groovy 中定义 PdfGenerator 接口的两种不同的实现 并直接在脚本中执行确定应该返回哪种实现的逻辑 清单 定义两种不同的 PdfGenerator 实现 并根据系统的属性选择使用一种实现
清单 Groovy 脚本中的多个类定义
class SimpleGroovyPdfGenerator implements PdfGenerator class ComplexGroovyPdfGenerator implements PdfGenerator def type = System properties[ generatorType ]if (type == simple ) return new SimpleGroovyPdfGenerator()else return new ComplexGroovyPdfGenerator()
如这段代码所示 可以通过用脚本编写的 bean 根据系统属性选择不同的实现 当 generatorType 系统属性为 simple 时 该脚本创建并返回一个 SimpleGroovyPdfGenerator 否则 它返回一个 ComplexGroovyPdfGenerator 由于简单和复杂的实现都实现了 PdfGenerator 接口 因此 Spring 应用程序中使用 pdfGenerator bean 的代码不必知道也不必关心实际的实现是什么
注意 仍然可以像 清单 那样在从脚本返回的 bean 上设置属性 所以 如果脚本返回一个 ComplexGroovyPdfGenerator 则设置该 bean 上的 panyName 属性 如果不需要定义多个实现 那么可以在 Groovy 脚本文件中仅定义一个类 如清单 所示 在这种情况下 Spring 发现并实例化这个惟一的类
清单 典型的 Groovy 脚本实现
class GroovyPdfGenerator implements PdfGenerator
至此 您可能想知道为什么 清单 将 bean 定义为一个 GroovyScriptFactory 那是因为 Spring 通过一个与 ScriptFactoryPostProcessor bean 结合的 ScriptFactory 实现(在这里是一个 Groovy 工厂)创建脚本对象 ScriptFactoryPostProcessor bean 负责用由工厂创建的实际对象替换工厂 bean 清单 显示添加后处理器 bean 的附加配置
清单 定义 ScriptFactoryPostProcessor bean
<bean class= springframework scripting support ScriptFactoryPostProcessor />
当 Spring 装载应用程序上下文时 它首先创建工厂 bean(例如 GroovyScriptFactory bean) 然后 执行 ScriptFactoryPostProcessor bean 用实际的脚本对象替换所有的工厂 bean 例如 清单 和 清单 中的配置产生一个名为 pdfGenerator 的 bean 它的类型是 groovierspring GroovyPdfGenerator (如果启用 Spring 中的 debug 级日志记录 并观察应用程序上下文的启动 将会看到 Spring 首先创建一个名为 scriptFactory pdfGenerator 的工厂 bean 然后 ScriptFactoryPostProcessor 从该工厂 bean 创建 pdfGenerator bean)
现在 您已知道使用 GroovyScriptFactory 和 ScriptFactoryPostProcessor 配置脚本编写的 Groovy bean 的底层细节 接下来我将展示一种更简单 更整洁的方法 这种方法可以得到相同结果 Spring 专门为创建脚本 bean 提供了 lang XML 模式 清单 使用 lang 模式定义 pdfGenerator bean
清单 使用 <lang groovy> 定义脚本 bean
<lang:groovy id= pdfGenerator script source= classpath:groovierspring/GroovyPdfGenerator groovy > <lang:property name= panyName value= Really Groovy Bookstore /></lang:groovy>
这段代码产生的 pdfGenerator bean 与 清单 和 清单 中更冗长的配置产生的 bean 是一样的 但是它更整洁 更简练 而且意图更清晰 <lang groovy> bean 定义需要 script source 属性 这告诉 Spring 如何找到 Groovy 脚本源代码 此外 可以使用 <lang property> 元素为脚本 bean 设置属性 使用 <lang groovy> 定义基于 Groovy 的 bean 是一种更好的选择 对阅读 Spring 配置的人而言 这种选项也更加清晰
配置内联 Groovy 脚本
为了实现完整性 我将介绍 Spring 还支持直接在 bean 定义中编写 Groovy 脚本 清单 使用一个内联脚本创建 pdfGenerator
清单 内联定义脚本 bean
<lang:groovy id= pdfGenerator > <lang:inline script> <![CDATA[ class GroovyPdfGenerator implements PdfGenerator ]]> </lang:inline script> <lang:property name= panyName value= Icky Groovy Bookstore /></lang:groovy>
这段代码使用 <lang groovy> 和 <lang inline script> 标记定义 pdfGenerator bean 它包含定义类的 Groovy 脚本 可以像前面一样使用 <lang property> 设置属性 您可能已经猜到 我不建议在 XML 配置文件中定义脚本 bean(或这一方面的任何类型的代码)
使用 Grails Bean Builder 配置 bean
Grails Web framework 在幕后依赖于 Spring Grails 提供了 Bean Builder 这是一个很棒的特性 让您可以使用 Groovy 代码编程式地 定义 Spring bean(参见 参考资料) 编程式地定义 bean 比 XML 配置更灵活 因为可以在 bean 定义脚本中嵌入逻辑 而这在 XML 中是不可能的 通过使用 Bean Builder 可以为已编译 Groovy 类和用脚本编写的 Groovy bean 创建 bean 定义 清单 使用已编译的 Groovy 类定义 pdfGenerator bean
清单 使用 Bean Builder 定义已编译的 Groovy bean
def builder = new grails spring BeanBuilder()builder beans pdfGenerator(GroovyPdfGenerator) panyName = Compiled BeanBuilder Bookstore def appContext = builder createApplicationContext()def generator = context pdfGenerator
清单 中的代码首先实例化一个 BeanBuilder 然后通过方法调用创建 bean 每个方法调用和可选的闭包参数定义一个 bean 并设置 bean 属性 例如 pdfGenerator(GroovyPdfGenerator) 定义一个名为 pdfGenerator 的 bean 其类型为 GroovyPdfGenerator 闭包中的代码则设置 panyName 属性 当然 在 beans 闭包中可以定义多个 bean
通过使用 Bean Builder 还可以从 Groovy 脚本而不是已编译的 Groovy 类创建 bean 但是 Bean Builder 没有 <lang groovy> 配置中的语法糖(syntactic sugar 即在计算机语言中添加的某种语法 这种语法对语言的功能并没有影响 但是更方便程序员使用) 所以需要将 bean 定义为 GroovyScriptFactory 并创建一个 ScriptFactoryPostProcessor bean 清单 是一个例子 展示如何使用 Bean Builder 配置用脚本编写的 Groovy bean
清单 使用 Bean Builder 定义用脚本编写的 Groovy bean
def builder = new grails spring BeanBuilder()builder beans pdfGenerator(GroovyScriptFactory classpath:groovierspring/GroovyPdfGenerator groovy ) panyName = Scripted BeanBuilder Bookstore scriptFactoryPostProcessor(ScriptFactoryPostProcessor)def appContext = builder createApplicationContext()def generator = context pdfGenerator
清单 中的代码在逻辑上等同于 清单 和 清单 中的 XML 配置 当然 清单 是使用 Groovy 代码来定义 bean 为了定义 pdfGenerator bean 清单 将类型指定为 GroovyScriptFactory 第二个参数指定脚本源代码的位置 和前面一样 在闭包中设置 panyName 属性 它还定义一个名为 scriptFactoryPostProcessor 的 bean 其类型为 ScriptFactoryPostProcessor 它将用实际的用脚本编写的对象替换工厂 bean
哪种配置选项最好?
至此 您已经看到配置基于 Groovy 的 bean(无论是已编译的还是用脚本编写的)的几种不同的方式 如果您仅是使用 Groovy 替代 Java 作为应用程序的主要语言 那么配置这些 bean 与配置基于 Java 的 bean 没有区别 对于已编译的 Groovy 类 可以使用 XML 或基于注释的配置进行配置
对于用脚本编写的 Groovy 对象 虽然可以用几种不同的方式来配置它们 但是 <lang groovy> 选项却是最简洁的方式 与使用 GroovyScriptFactory 和 ScriptFactoryPostProcessor 或者使用 <lang inline script> 进行配置相比 这种选项能够最清晰地表现意图
您还看到了 Grails Bean Builder 它以完全不同的方式创建大多数 Spring 应用程序使用的 Spring 应用程序上下文 如果要用 Groovy 创建所有的 bean 并且要能够添加逻辑到 bean 构建过程中 Bean Builder 必须很好地符合要求 另一方面 使用 Bean Builder 定义 Groovy bean 时 需要使用 GroovyScriptFactory 和 ScriptFactoryPostProcessor 来定义 bean
使用 Groovy bean
bean 配置和可用的几个选项是集成 Groovy 和 Spring 的难点(但是如您所见 这并不是很难) 实际上 在 Spring 应用程序中使用 Groovy bean 很容易 Spring 的动态语言支持使得 bean 的使用对于应用程序代码是完全透明的 应用程序代码不需要知道也不需要关心实现细节 您可以像平常开发 Spring 应用程序一样编写应用程序代码 并且可以利用 Spring 提供的所有特性 例如依赖项注入 AOP 和与第三方框架集成
清单 展示了一个简单的 Groovy 脚本 它从 XML 配置文件创建一个 Spring 应用程序上下文 获取 PDF 生成器 bean 并使用它生成一个发票的 PDF 版本
清单 在脚本中使用 Groovy bean
def context = new ClassPathXmlApplicationContext( applicationContext xml )def generator = context getBean( pdfGenerator )Invoice invoice = new Invoice(orderNumber: orderDate: new Date())invoice lineItems = [ new LineItem(quantity: description: Groovy in Action (ebook) price: ) new LineItem(quantity: description: Programming Erlang price: ) new LineItem(quantity: description: iText in Action (ebook) price: )]byte[] invoicePdf = generator pdfFor(invoice)FileOutputStream file = new FileOutputStream( Invoice $invoice orderNumber pdf )file withStream file write(invoicePdf)println Generated invoice $invoice orderNumber
在 清单 中 大部分代码用于创建 Spring ApplicationContext 创建发票并将它写出到一个文件 使用 pdfGenerator bean 生成发票仅需一行代码 在通常的 Spring 应用程序中 在应用程序启动时引导一次应用程序上下文 然后 应用程序中的组件只需使用 Spring 为它们提供的依赖项 在 Spring Web 应用程序中 可以配置一个 servlet 上下文侦听器 在应用程序启动时引导 Spring 例如 可以定义一个 PDF 发票生成服务 如清单 所示
清单 使用 PDF 生成器的服务类
@Servicepublic class InvoicePdfServiceImpl implements InvoicePdfService @Autowired private PdfGenerator pdfGenerator; public byte[] generatePdf(Long invoiceId) Invoice invoice = getInvoiceSomehow(invoiceId); return pdfGenerator pdfFor(invoice); // Rest of implementation
清单 中的 InvoicePdfServiceImpl 类刚好被实现为一个 Java 类 它依赖于 PdfGenerator 可以很方便地将它实现为 Groovy bean 可以通过任何以编译的或用脚本编写的 bean 配置来使用 GroovyPdfGenerator 实现 而 InvoicePdfServiceImpl 对此一无所知 因此 使用 Groovy(或任何动态语言)对应用程序代码而言是透明的 这样很好 因为实现了组件之间的松散耦合 从而使单元测试更加容易 并且可以使用最适合的实现语言
结束语
您已经看到了配置 Groovy 语言 bean 的一些不同的方式 以及在基于 Spring 的应用程序中使用它们是多么容易 您可以像使用 Java 类一样使用已编译的 Groovy 类 您还看到了配置用脚本编写的 Groovy 对象的一些不同的方式 应该选择的选项取决于如何在应用程序中使用 Groovy 还可以在同一个应用程序中结合使用已编译的和用脚本编写的 Groovy bean 实际上 如果希望的话 还可以在同一个应用程序中同时使用 Java Groovy JRuby 和 BeanShell bean 但我不建议这样做 作为开发人员 必须权衡在同一应用程序中使用多种语言的优点和缺点
作为一种语言 Groovy 比 Java 更灵活 这使它成为很有吸引力的选择 即使仅选择编译 Groovy 类也是如此 Spring 可以集成用脚本编写的动态语言 bean 这使人们更加喜欢选择 Groovy 因为可以在用脚本编写的 bean 中引入附加的逻辑和灵活性 例如 正如前面看到的那样 可以根据业务逻辑添加确定应用程序启动时应该实例化的 bean 类型的逻辑 或者 可以将用脚本编写的对象部署到 groovy 文件中 使 Web 应用程序的部署更加灵活 groovy 文件位于应用程序的 CLASSPATH 中或文件系统中的某个地方 而不是打包在 WAR 文件中
到目前为止 您看到的所有东西都为 Spring 工具箱增加了灵活性和威力 但是 Spring 动态语言支持中最引人注目的特性可能是在应用程序运行时 监视和检测对动态语言脚本的更改 并在 Spring 应用程序上下文中自动重新装载 更改后的 bean 第 部分将深入探索这个功能 包含 bean 的静态配置在运行时不能更改 与之对比 这个功能提供了很大的灵活性
下载
描述名字大小 下载 样例代码 j groovierspringcode zip MB 点击
参考资料
cha138/Article/program/Java/ky/201311/28438相关参考
Spring系列第1部分:Spring框架简介(图) 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
面试是你整个求职过程中最重要的阶段。成败均决定于你面试时的短短一瞬间的表现。每个人都能够学会怎么出色地面试,而且绝大多数的错误都可以预期并且避免,下面这24条提示将给你带来成功的契机。1、带多几份履历
Spring操作Hibernate更方便 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 软件系统
李明是一位工作表现出色的基层管理人员,在被提升为部门经理,进而提升为总经理后,虽然工作比以前更努力,绩效都一直较差,其中
李明是一位工作表现出色的基层管理人员,在被提升为部门经理,进而提升为总经理后,虽然工作比以前更努力,绩效都一直较差,其中的原因很可能就在于李明并没有培养起从事髙层管理工作所必需的_____。A、概念技
用spring来管理项目的数据库部分往往比自己去写连接要容易管理的多步骤也比较简单 项目根目录下建立conflib目录将spring相关包coop到lib中并导入建立个文件jdbcpropert
地表上向外涌水的天然出口,涌水量从涓涓小滴到每天达数百万公升不等。泉与向外渗水的不同处,通常在于水量更大,水量更集中。二者差别在于地下条件的不同。如果透水岩层下面垫有不透水岩层,不透水岩层又裸露在坡面
玻璃门首要考虑的是安全第一。要做到安全牢固,其固定部分的安装最重要。那么,其固定部分安装怎样才能更牢固?(1)在安装玻璃之前,门框的不锈钢板或其他饰面包覆安装应完成,地面的装饰施工也应完毕。门框顶部的
Groovy轻松入门—搭建Groovy开发环境 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 由
知识大全 Spring 3.0 M2发布 大部分新特性开发完成
Spring3.0M2发布大部分新特性开发完成 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 期
一段短短的自我介绍,其实是为了揭开更深入的面谈而设的。 一分钟的自我介绍,犹如商品广告,在短短六十秒内,针对“客户”的需要,将自己最美好的一面,毫无保留地