本周的 Spring:2011 年 7 月 19 日
欢迎阅读新一期的本周的 Spring。有很多精彩内容,让我们开始吧。
- Grails 倡导者 Peter Ledbrook 的网络研讨会“调优 Grails 应用”的视频已在此提供。其中包含许多对普通 Web 开发人员以及特定 Grails 开发人员有益的精彩内容。请务必查看SpringSource YouTube 频道上的其他精彩内容。
- OSCON 即将到来,SpringSource 将全力参与!来 OSCON(以及 OSCON Java 和 OSCON Data!)见我本人 (Josh Long)、Steve Mayzak、Ezra Zygmuntowicz、Derek Collison、Bruce Snyder、David McCrory、James Watters 等人,听他们谈论 Spring、CloudFoundry 等更多内容。此外,欢迎参观我们的展位,我们将很乐意回答问题,向您介绍新技术并进行交流。您会去吗?请告诉我们,通过 Twitter 向@SpringSource发送消息。
- Spring Data Redis 1.0.0.M4 已发布。新版本包含多项改进。我最喜欢的是什么?一个使用 Redis 的 Spring 3.1
CacheManager
实现!开箱即用,Spring 3.1 的缓存抽象支持基于java.util.Map<K,V>
接口的CacheManager
实现以及 Ehcache 实现。Spring Gemfire 项目也附带一个委托给 GemFire 的CacheManager
实现。这个新的 Redis 实现增加了已有选项的多样性,而 Spring 3.1 甚至还没有正式发布 (GA)! - 说到 Redis,请关注这个即将到来的网络研讨会:Spring Data Redis 入门。根据描述,“本次网络研讨会将介绍 Redis 及其数据结构、其背后的基本概念以及 Spring Data 中的 Redis 支持,并将展示在 Cloud Foundry 等云环境中入门和扩展是多么容易。” 请务必收看!
<LI> <a href="http://www.springsource.org/node/3183">Spring Integration 2.0.5 has just been released.</a>
This release addresses 48 issues of which roughly half were bugs and half were improvements. For details <A href="https://jira.springsource.org/secure/ReleaseNote.jspa?projectId=10121&version=12104">see the Release Notes</a>. </li>
<LI>Dr. David Syer, lead of the <a href="http://static.springsource.org/spring-batch/">Spring Batch project,</a> lead of the Spring Hadoop project, committer on just about everything else, and nice guy, all around, has just posted an amazingly clear…
支持 Neo4j 的 Spring Data Graph 1.1.0.M2 发布
亲爱的 Spring 社区,
我们很高兴地宣布,支持 Neo4j 的 Spring Data Graph 项目的新里程碑版本 (1.1.0.M2) 现已可用!
Spring Data 项目的主要目标是让使用非关系型数据库、MapReduce 框架和基于云的数据服务等新兴数据访问技术构建 Spring 应用变得更容易。
Graph Neo4j 模块提供了与 Neo4j 图数据库的集成。早在 2010 年,Rod Johnson 和 Emil Eifrem 开始构思 Spring 与 Neo4j 的集成,包括透明持久化和……
Spring GemFire 1.1.0.M1 for Java 发布
亲爱的 Spring 社区,
我们很高兴地宣布 Spring GemFire 1.1 项目的首个里程碑版本现已可用!Spring GemFire 项目旨在使使用 GemFire 作为分布式数据管理平台构建基于 Spring 的高可伸缩应用变得更容易。
新的里程碑更新包括
- 原生支持即将发布的 GemFire 6.6
- CacheServer 支持
- Spring 3.1 缓存抽象的 GemFire 实现
- 支持带可变参数的查询
要了解更多关于该项目的信息,请访问 Spring GemFire 主页。
立即下载:Spring GemFire for Java | Spring GemFire for .NET
我们期待您的反馈!
社交编码:Pull Requests - 当事情变得复杂时怎么办
场景:你想为一个托管在公共 git 仓库服务(如 GitHub)上的开源项目贡献代码。许多人向我参与的项目提交 pull request,很多时候这些 pull request 合并起来比预期的要复杂,这会稍微减慢流程。基本工作流程在概念上很简单
- fork(派生)一个公共开源项目
- 在本地对其进行一些更改,然后推送到你自己的远程 fork
- 请项目负责人将你的更改合并到主代码库
在 Keith Donald 的一篇博客中对此基本工作流程有很好的说明。
当你 fork 代码库到发送 pull request 之间主代码库发生变化,或者(更糟的是)你想为不同的功能或错误修复发送多个 pull request,并且需要将它们分开以便项目所有者能够单独处理时,就会出现复杂情况。本教程旨在帮助你使用 Git 处理这些复杂情况。
这里的描述使用了 GitHub 领域的语言(如“pull request”、“fork”、“merge”等),但同样的原理也适用于其他公共 Git 服务。为了本教程的目的,我们假设公共项目在其 master 分支上接受 pull request。大多数 Spring 项目都是这样工作的,但其他一些公共项目则不是。你可以在下面的描述中将“master”一词替换为正确的 Gits分支名称,示例也应大致正确。
为了帮助您跟踪本地发生了什么,下面以“$”开头的 shell 命令可以提取到脚本中并按出现的顺序运行。终点应是一个名为“work”目录中的本地仓库,该仓库的 origin 链接到其 master 分支(模拟远程公共项目),并在私有 fork 上有两个分支。这两个分支的 HEAD 内容相同,但提交历史不同(如下面的 ASCII 图所示)。
两个远程仓库
如果要发送 pull request,涉及到两个远程仓库:主公共项目,以及你推送更改的 fork。
在某种程度上这是个人偏好问题,但我喜欢做的是将主项目作为我工作副本的远程“origin”,并使用我的 fork 作为第二个远程,命名为“fork”。这样做很容易跟踪主项目中发生的事情,因为我只需要做以下操作:
# git fetch origin
所有更改都将在本地可用。这也意味着当我执行自然的 Git 工作流时,我永远不会感到困惑
# git checkout master
# git pull --rebase
... build, test, install etc ...
这总能使我的本地仓库与主项目保持最新。在从 master 分支拉取后,我可以通过执行以下操作轻松地使我的 fork 与主项目同步
# git push fork
初始设置
让我们在沙箱中创建一个简单的“远程”仓库来操作。我们将直接在你的文件系统中本地创建(以 UN*X 命令为例),而不是使用 Git 服务提供商。
$ rm -rf repo fork work
$ git init repo
$ (cd repo; echo foo > foo; git add .; git commit -m "initial"; git checkout `git rev-parse HEAD`)
(最后那个 checkout 是为了让仓库处于 detached head 状态,这样我们以后就可以从克隆中推送到它。)从现在开始,假设“repo”是一个公共 GitHub 项目(例如 git://github.com/SpringSource/repo.git
)。
此克隆命令中的“fork”URL 将类似于 [email protected]/myuserid/repo.git
。现在我们将创建 fork。这相当于 GitHub 在你请求 fork 仓库时所做的事情
$ git clone repo fork
$ (cd fork; git checkout `git rev-parse HEAD`)
最后,我们需要设置一个工作目录来存放我们的更改(记住“repo”= git://github.com/SpringSource/repo.git
)
$ git clone repo work
$ cd work
$ git checkout origin/master
因为我们克隆了主要的公共仓库,所以它默认是远程“origin”。我们将添加一个新的远程,以便可以推送我们的更改
$ git remote add fork ../fork
$ git fetch fork
$ git push fork
本地仓库现在只有一个提交,在 gitk
(或你最喜欢的 Git 可视化工具)中看起来像这样
A (origin/master, fork/master, master)
在此图中,“A”是提交标签,括号中列出了与该提交关联的分支。
获取最新内容
你可以始终使用以下命令从主仓库获取最新内容
# git checkout master
# git pull --rebase
并与你的 fork 同步
# git push fork
如果采用这种操作方式,尽可能地保持主仓库和你的 fork 之间的 master 分支同步,并且绝不在 master 分支上进行任何本地更改,你将永远不会对其他人所处的位置感到困惑。此外,如果你要向同一个公共项目发送多个 pull request,只要将它们保存在各自独立的分支上(即不在 master 分支上),它们就不会相互重叠。
Pull Request
当你想开始一个 pull request 的工作时,从如上所示的完全同步的 master 分支开始,并创建一个新的本地分支
$ git checkout -b mynewstuff
进行更改,测试等
$ echo bar > bar
$ echo myfoo > foo
$ git add .
$ git commit -m "Added bar, edited foo"
然后使用新的分支名称(而不是 master)将其推送到你的 fork 仓库
$ git push fork mynewstuff
如果 origin 中没有发生变化,你可以从那里发送 pull request。
如果 Origin 发生变化怎么办?
为了本教程的目的,我们像这样模拟 origin 中的一个变化
$ cd ../repo
$ git checkout master
$ echo spam > spam; git add .; git commit -m "add spam"
$ git checkout `git rev-parse HEAD`
$ cd ../work
现在我们准备好应对变化了。首先我们将本地 master 更新到最新
$ git checkout master
$ git pull
$ git push fork
本地仓库现在看起来像这样
A -- B (mynewstuff, fork/mynewstuff)
\
-- D (master, fork/master, origin/master)
注意你的新内容没有 origin/master
作为直接祖先(它在另一个分支上)。这使得项目所有者难以合并你的更改。你可以通过在本地自己做一些工作,并在发送 pull request 之前将其推送到你的 fork 来简化操作。
重写分支历史
如果你没有在你的分支上与任何人协作,完全可以将代码 rebase 到远程仓库的最新更改上,然后强制推送
# git checkout mynewstuff
# git rebase master
如果你的更改与远程仓库中发生的某些事情不兼容,rebase 可能会失败。在继续之前,你需要解决冲突并提交。这会让你自己感到困难,但会使远程项目所有者感到容易,因为 pull request 保证能成功合并。
在重写历史时,你可能想将一些提交合并 (squash) 到一起,以便补丁更容易阅读,例如
# git rebase -i HEAD~2
...
无论如何(即使 rebase 顺利进行),如果你已经推送到你的 fork,你需要强制执行下一次推送,因为它已经重写了历史(假设远程仓库已发生变化)。
# git push --force fork mynewstuff
本地仓库现在看起来像这样(B
提交实际上与之前的版本不完全相同,但这里的区别并不重要)
A -- D (master, fork/master, origin/master) -- B (mynewstuff, fork/mynewstuff)
你的新分支有一个直接的祖先是 origin/master
,这样每个人都会很高兴。然后你就可以进入 GitHub UI,针对 repo:master
发送你的分支的 pull request 了。
如果我想保留我的本地提交怎么办?
如果你在本地分多个步骤提交了更改,你可能想保留所有细小的提交,并且仍然将你的 pull request 作为单个提交呈现给远程仓库。没关系,你可以为此创建一个新分支,然后从那里发送 pull request。如果你在你的功能分支上与某人协作并且不想强制推送,这也是一个好办法。
首先我们将新内容推送到 fork 仓库,以便我们的协作者可以看到(如果你想将更改保留在本地,则此步骤不是必需的)
$ git checkout mynewstuff
$ git push fork
然后我们将为合并后的 pull request 创建一个新分支
$ git checkout master
$ git checkout -b mypullrequest
$ git merge --squash mynewstuff
$ git commit -m "comment for pull request"
$ git push fork mypullrequest
这是本地仓库
A -- B (mynewstuff, fork/mynewstuff)
\
-- D (master, fork/master, origin/master) -- E (mypullrequest, fork/mypullrequest)
你可以继续进行操作,你的新分支有一个直接的祖先是 origin/master
,因此合并将是轻而易举的。
如果你没有在 mynewstuff
分支上协作,你甚至可以在此时将其丢弃。我经常这样做以保持我的 fork 整洁
# git branch -D mynewstuff
# git push fork :mynewstuff
这是本地仓库,与其两个远程仓库完全同步
A -- D (master, fork/master, origin/master) -- E (mypullrequest, fork/mypullrequest)
继续开发你的新内容
假设你的 pull request 被拒绝,项目所有者希望你进行一些更改,或者新内容变得更有趣,你需要对其进行更多工作。
如果你没有在上面删除它,你可以继续在你的粒度分支上工作...
$ git checkout mynewstuff
$ echo yetmore > foo; git commit -am "yet more"
$ git push fork
然后当你准备好时,将更改转移到 pull request 分支
$ git rebase --onto mypullrequest master mynewstuff
我们想要的所有更改现在都已到位,但分支位于错误的提交上。如下所示,mynewstuff
是我希望 mypullrequest
所在的位置,而远程 fork/mynewstuff
没有对应的本地分支
A -- B -- C (fork/mynewstuff)
\
-- D (master, fork/master, origin/master) -- E (mypullrequest, fork/mypullrequest) -- F (mynewstuff)
我们可以使用 git reset
将这两个分支切换到我们想要的位置(如果你喜欢,你可能可以在图形界面中完成此操作)
$ git checkout mypullrequest
$ git reset --hard mynewstuff
$ git checkout mynewstuff
$ git reset --hard fork/mynewstuff
新的仓库看起来像这样
A -- B -- C (mynewstuff, fork/mynewstuff)
\
-- D (master, fork/master, origin/master) -- E (fork/mypullrequest) -- F (mypullrequest)
如果我们对 pull request 包含 2 个提交没问题,我们可以直接将其推送
$ git checkout mypullrequest
$ git push fork
终点看起来像这样
A -- B -- C(mynewstuff, fork/mynewstuff)
\
-- D (master, fork/master, origin/master) -- E -- F (mypullrequest, fork/mypullrequest)
或者我们可以 rebase 它将提交合并在一起并强制推送,示意图如下
# git rebase -i HEAD~2
...
# git push --force fork
因为 origin/master
是 fork/mypullrequest
的直接祖先,我知道我的 pull request 将非常容易合并。
总结
希望本教程为您提供了足够的 Git “弹药”,可以放心地对您喜爱的开源项目进行一些更改,并且有信心合并将很容易。请记住,总是有不止一种方法可以做到,并且 Git 是一个强大、低级的工具,因此您的具体情况可能会有所不同,您可能会发现上述方法的变体更可取甚至必要,具体取决于您的更改。
Spring Data Redis 1.0.0.M4 发布
亲爱的 Spring 社区,
我很高兴地宣布 Spring Data Redis 1.0 项目的第四个里程碑版本现已可用!
此版本引入了几个新功能,例如
- Spring 3.1 的 Redis 缓存实现
- 简化的发布-订阅命名空间
此外,在此版本中,Spring Data Key Value 项目已拆分为 Spring Data Redis 和 Spring Data Riak。
要了解更多关于 Redis 和 Spring Redis 的信息,请参加即将举行的由 Salvatore Sanfilippo (Redis 作者) 和 Costin Leau (Spring Redis 负责人) 主讲的网络研讨会。
本周的 Spring:2011 年 7 月 12 日
欢迎阅读新一期的“本周的 Spring”。今天迎来了一个新的日出,更重要的是,vSphere 5 发布了,这是云基础设施的下一步!
我的头仍然在因今天早上发布的兴奋感而嗡嗡作响。
这——以及最近发布的 vFabric 5——代表着云创新的下一个阶段,也是使用 Spring 将你的应用投入生产和迁移到云中的重要一步。
<LI>O'Reilly has published a fantastic roundup on the <a href = "http://radar.oreilly.com/2011/07/7-java-projects.html">seven Java projects that <EM…
S2G Forum 2011 演示文稿
Rod Johnson 在 S2G Forum 2011 的主题演讲
其他演示文稿
Spring MVC 3.1 更新 - Rossen Stoyanchev 本次会议将深入探讨 Spring MVC 3.1 相关更新的更多细节。主要议题包括处理注解控制器方法的新基础设施、命名空间配置改进、会话管理以及 Servlet 3.0 支持。 |
Spring Integration 更新 - Josh Long 本次会议将带您了解 Spring Integration 2.0 的新特性,包括新的 Spring Integration ROO 插件。在此过程中,您将了解 Spring Integration 对 Spring Framework 3.0 特性的支持,例如 Spring Expression Language、ConversionService 和 RestTemplate。您还将了解几个新的适配器,包括 AMQP、XMPP、TCP/UDP、JDBC、JMX 等等。 |
在虚拟环境中调优 Java - Ben Corrie 本次实践会议将详细探讨如何在虚拟环境中运行 JVM 时获得最佳性能,特别关注内存管理。会议将花费一些时间回顾现有的最佳实践及其背后的技术原因,同时还将提供最新的数据和建议,以及 SpringSource 为增强 Java 在虚拟环境中的表现所做工作的未来展望。 |
面向 Spring 开发者的 Cloud Foundry - Josh Long Cloud Foundry 是 VMware 推出的新的开源平台即服务 (Platform-as-a-Service),它提供了一个出色的部署平台,可在自动伸缩、自动管理的云环境中运行 Spring 应用。本次演示文稿描述了如何利用 MongoDB、Redis 和 RabbitMQ 等云服务,并阐释了 Java 在 Cloud Foundry 上执行的架构细节。 |
Apache Tomcat 7 更新 - Mark Thomas Apache Tomcat 是当今企业市场中使用最广泛的应用服务器。开发人员、QA 团队和 IT 经理都在各种部署中成功地使用 Tomcat。本次会议将深入探讨流行的 Apache 项目,分析 Apache Tomcat 7 中可用的新功能,包括异步请求处理、内存泄漏检测/预防和安全增强。 |
Spring AMQP 与 Rabbit 消息传递 - Dave Syer Spring AMQP 项目的目标是简化基于 AMQP 协议的消息传递应用的开发。Spring AMQP 提供跨 RabbitMQ 和 Apache Qpid 实现的可移植 Java 和 .NET API,以及促进基于 POJO 编程模型的便捷抽象。如果您熟悉 Spring 的 JMS 支持,您会觉得很熟悉。本次会议将带您了解 Spring AMQP 的特性,例如发布、消息转换器以及创建多线程消费者。还将介绍对 RabbitMQ 服务器管理的支持以及如何使用 Spring 进行配置。 |
使用 Gemfire 实现缓存和可伸缩数据访问 - Costin Leau 务实地探讨如何在 Spring 应用中通过缓存轻松获得提升。本次会议将分析常见应用堆栈中通常遇到的瓶颈及其解决方法。将讨论各种缓存模式,重点不仅在于性能,还在于可伸缩性,包括如何充分利用 vFabric Gemfire。 |
云中的 Grails - Peter Ledbrook 本次演示文稿将概述提供 Grails 支持的各种云运行时平台,并讨论每个平台固有的设计约束。本次会议将提供具体建议,指导您如何设计 Grails 应用以充分利用这些新的部署目标。 |
调优 Grails 应用 - Peter Ledbrook Grails 使 Web 应用的启动和运行变得异常容易,但它并不能保证应用的性能和可伸缩性。如果每个请求发出数百个数据库查询,您的应用就不会像“飞毛腿”一样快。了解如何追踪和修复应用各个部分的瓶颈,特别是数据库访问和视图渲染。 |
Spring Roo 1.1.5 发布
亲爱的 Spring 社区,
我们很高兴地宣布 Spring Roo 1.1.5 已发布(点此下载)。Spring Roo 是一个用于 Java 的快速应用开发工具,只需几分钟即可创建完整的企业应用。
自 1.1.4 版本以来,新版本包含超过 95 项改进和错误修复。Roo 的下一个版本将是 1.2.0.RC1,其中将引入新的功能,例如应用分层支持和新的 JSF UI 选项。
此外,请查看面向 Spring Roo 的 Vaadin 插件教程。
Spring Roo 拥有非常活跃的社区和响应迅速的开发团队,因此如果您对此新版本有任何疑问,请随时在社区论坛上咨询Spring Roo 工程团队。您也可以在 Twitter 上找到我们 - 关注 @SpringRoo…