本周 Spring:2011 年 8 月 2 日

工程 | Josh Long | 2011 年 8 月 3 日 | ...

欢迎来到另一期“本周 Spring”。八月已过大半,不久之后,在八月末,VMworld 2011 将拉开帷幕。紧接着,SpringOne 也将来临。节奏会变得非常紧凑,所以做好准备!本周的“本周 Spring”有很多来自 Chariot Solutions 的 Gordon Dickens 的有趣内容。感谢 Gordon 提供的精彩阅读!

  1. Spring 的创始人兼思想领袖 Rod Johnson 今年早些时候在 TheServerSide 发表了主题演讲。这篇博文转载了主题演讲的部分内容,包括他对云计算、SOA 等的思考。快来看看吧。
  2. <LI> 
    	The video of the recent webinar, "<A href="http://www.springsource.org/node/3194">What's New in Apache Tomcat 7</a>," is now available on the <a href="http://www.youtube.com/SpringSourceDev">SpringSourceDev YouTube channel</a>.   
    </LI> 
    <LI>Luke Taylor has some great content on how to <a href="http://blog.springsource.com/2011/08/01/spring-security-configuration-with-scala/">configure Spring Security with the Scala DSL</a> he's been developing. Check it out! 
    </LI> 
    <LI> 
    	<a href= "http://www.springsource.org/node/3192">Spring Data JDBC Extensions with Oracle Database Support</a>…

调试 DSLD 脚本

工程 | Andrew Eisenberg | 2011 年 8 月 2 日 | ...

不久前,我为 Groovy-Eclipse 引入了DSLD(DSL 描述符)。DSLD 是 Groovy 脚本,为 Eclipse 工作空间中的 Groovy 项目提供丰富的编辑支持(内容辅助、导航等)。由于 DSLD 只能在运行的 Eclipse 进程中执行,因此调试不像启动 Eclipse 调试器并单步执行 Groovy 脚本那么简单。在这篇文章中,我将描述一些简单和更复杂的技术,您可以使用这些技术来调试您的 DSLD。

要让这一切正常工作,您需要最新的开发版本

简单粗暴

调试 DSLD 最简单粗暴的方法是使用 println。这将把表达式打印到运行的 Eclipse 进程的标准输出,如果您从命令行启动 Eclipse,就可以看到。但是,我建议改用 log 语句。这将把日志信息打印到 Groovy 事件控制台

使用 Scala 配置 Spring Security

工程 | Luke Taylor | 2011 年 8 月 1 日 | ...

在之前的一篇文章《Spring Security 命名空间的幕后》中,我谈到了 Spring Security 命名空间如何成功地提供了一种简单的替代纯 Spring bean 配置的方法,但当您想要开始自定义其行为时,学习曲线仍然很陡峭。在 XML 元素和属性的背后,创建并连接了各种过滤器和帮助策略,但是,除了阅读处理 XML 解析的代码之外,没有简单的方法可以找出涉及哪些类或它们如何交互的细节。

一段时间以来,我们一直在尝试使用 Spring 的 @Configuration提出一种基于 Java 的替代解决方案,该解决方案既能保留 XML 命名空间的简单性,又能使底层行为更加透明且易于自定义。虽然理论上可行,但似乎没有一个基于 Java 的解决方案能够满足...

微调 Spring Data Repositories

工程 | Oliver Drotbohm | 2011 年 7 月 27 日 | ...

距离我们发布 Spring Data JPA 1.0 GA 才几天,这是 Spring Data 项目的第一个主要版本,它在我们的 Spring Data Commons 模块中附带了 repository 抽象的实现。repository 抽象由三个主要部分组成:定义 repository 接口、暴露 CRUD 方法和添加查询方法。添加查询方法已在第一篇 Spring Data JPA 博客文章中详细讨论。但是定义 repository 接口和暴露 CRUD 方法在之前的博客文章中引发了相当多的问题。这就是为什么我们将...

本周 Spring:2011 年 7 月 26 日

工程 | Josh Long | 2011 年 7 月 26 日 | ...

欢迎回到另一期《本周 Spring》!本周 @springsource 出席了在俄勒冈州波特兰举行的 OSCON(以及 OSCON Java 和 OSCON Data)。如果您在这里,请参观我们在展厅的展位,或查看日程安排中的众多 Spring 演讲!

如果您错过了我们在 OSCON 的活动,或者您只是想获得更好的 Spring 体验,请务必注册参加 SpringOne 2GX 2011,这是 Spring、Grails 和 CloudFoundry 开发者的首要盛会。SpringOne 2GX 是一个独一无二的会议,面向开发业务应用程序、创建多设备感知的 Web 应用程序、设计云架构以及管理高性能基础架构的应用程序开发者、解决方案架构师、Web 运营和 IT 团队。会议课程专为使用广受欢迎的开源 Spring 技术、Groovy & Grails 和 Tomcat 的开发者量身定制。无论您是构建和运行关键业务应用程序,还是设计下一个杀手级云应用程序,SpringOne 2GX 都将帮助您及时了解最新的企业技术。

  1. OSCON 很棒,但我会花一个小时观看 Spring Data Redis 入门网络研讨会,面向北美,以及面向欧洲
    You should too: <a href="https://redis.ac.cn/">Redis</a> is an open source, advanced key-value store known for its excellent performance, its small footprint and embed-ability. <a href="http://www.springsource.org/spring-data/redis">The Spring Data</a> project makes it easier to build Spring-powered applications that use new data access technologies such as non-relational "NOSQL" databases and cloud based data services. Check it out!  </li>
    
  2. <a href= "http://www.springsource.org/node/3189">Spring Data Graph 1.1.0.RC1 with Neo4j support Released</a>
    The key changes in the Spring Data Graph 1.1.…

本周 Spring:2011 年 7 月 19 日

工程 | Josh Long | 2011 年 7 月 20 日 | ...

欢迎回到另一期《本周 Spring》。有很多好东西要介绍,所以让我们开始吧。

  1. Grails 倡导者 Peter Ledbrook 关于“调优您的 Grails 应用程序”网络研讨会的视频已在此提供。对于一般的 Web 开发者,特别是 Grails 开发者来说,有很多很棒的技巧。请务必查看 SpringSource YouTube 频道上的其他精彩内容。
  2. OSCON 近在咫尺,SpringSource 将全力出席!快来听听我(Josh Long)、Steve Mayzak、Ezra Zygmuntowicz、Derek Collison、Bruce Snyder、David McCrory、James Watters 等人在 OSCON(以及 OSCON Java 和 OSCON Data!)上关于 Spring、CloudFoundry 等内容的演讲。此外,也请随意参观我们的展位,我们将乐意回答您的问题,向您介绍新技术,并与您见面交流。要去参加吗?请告诉我们,通过 Twitter @SpringSource 给我们发消息。
  3. 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 甚至还没有正式发布!
  4. 说到 Redis,请查看即将举行的网络研讨会《Spring Data Redis 入门》。描述中写道:“本次网络研讨会将介绍 Redis、其数据结构、其背后的基本概念以及 Spring Data 中的 Redis 支持,并将展示在 Cloud Foundry 等云环境中轻松入门和横向扩展的便捷性。” 务必收听!
  5. 		  <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…

社交编码:拉取请求 - 当事情变得复杂时该怎么办

工程 | Dave Syer | 2011 年 7 月 18 日 | ...

场景:您想为托管在 github 等公共 git 仓库服务上的开源项目贡献代码。很多人向我参与的项目发送拉取请求,很多时候它们的合并比应有的复杂,这会稍微减慢流程。基本工作流程概念上很简单:

  1. fork 一个公共开源项目
  2. 在本地对其进行一些更改并将其推送到您自己的远程 fork
  3. 请求项目负责人将您的更改与主代码库合并

有关此基本工作流程的精彩描述,请参阅 Keith Donald 的博客文章

当您 fork 项目和发送拉取请求之间主代码库发生更改时,或者(更糟糕的是)您想为不同的功能或 bug 修复发送多个拉取请求,并且需要将它们分开以便项目所有者可以单独处理时,复杂性就出现了。本教程旨在帮助您使用 git 解决这些复杂问题。

这里的描述使用了 github 领域语言(“拉取请求”、“fork”、“合并”等),但同样的原则适用于其他公共 git 服务。在本教程中,我们假设公共项目在其 master 分支上接受拉取请求。大多数 Spring 项目都这样做,但其他一些公共项目则不然。您可以将下面的“master”替换为正确的分支名称,所有示例应该大致正确。

为了帮助您跟踪本地发生的情况,以下以“$”开头的 shell 命令可以提取到脚本中并按顺序运行。终点应该是一个本地仓库,位于名为“work”的目录中,其 origin 连接到其 master 分支(模拟远程公共项目),并在私有 fork 上有两个分支。这两个分支的 HEAD 内容相同,但提交历史不同(如下图 ASCII 图所示)。

两个远程仓库

如果您要发送拉取请求,涉及两个远程仓库:主公共项目和您推送更改的 fork。

在某种程度上这取决于个人偏好,但我喜欢做的是将主项目设为我的工作副本的远程“origin”,并将我的 fork 用作名为“fork”的第二个远程。这样可以轻松跟踪主项目中发生的情况,因为我只需

# git fetch origin

所有更改都可以在本地获得。这也意味着当我执行我的自然 git 工作流程时,我永远不会感到困惑

# git checkout master
# git pull --rebase
... build, test, install etc ...

这总是使我与主项目保持同步。通过在从 master pull 之后执行此操作,我可以简单地保持我的 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 是将仓库留在分离头状态,以便稍后我们可以从克隆推送到它。)从现在开始,假装“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

如果您以这种方式操作,尽可能保持 master 在主仓库和您的 fork 之间同步,并且永远不对 master 分支进行任何本地更改,那么您将永远不会对世界其他地方的情况感到困惑。此外,如果您要向同一个公共项目发送多个拉取请求,如果您将它们分别放在各自的分支上(即不在 master 上),它们就不会相互重叠。

拉取请求

当您想开始处理拉取请求时,从完全最新的 master 分支开始,并创建一个新的本地分支

$ git checkout -b mynewstuff

进行更改、测试等

$ echo bar > bar
$ echo myfoo > foo
$ git add .
$ git commit -m "Added bar, edited foo"

并将其推送到您的 fork 仓库,使用新的分支名称(不是 master)

$ git push fork mynewstuff

如果 origin 没有变化,您可以从那里发送拉取请求。

如果 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 作为直接祖先(它位于另一个分支上)。这使得项目所有者合并您的更改变得很麻烦。您可以通过在本地自行完成一些工作,并在发送拉取请求之前将其推送到您的 fork 来使其更容易。

重写您分支上的历史记录

如果您没有与任何人协作在您的分支上,那么将您的分支 rebase 到远程仓库的最新更改上并强制推送应该是完全没问题的。

# git checkout mynewstuff
# git rebase master

如果您所做的更改与远程仓库中发生的事情不兼容,rebase 可能会失败。您需要解决冲突并提交,然后才能继续。这会给您带来麻烦,但对远程项目所有者来说很容易,因为拉取请求保证能成功合并。

在您重写历史记录时,也许您想将一些提交合并(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 发送您分支的拉取请求了。

如果我想保留我的本地提交怎么办?

如果您分步提交了您的更改,也许您想保留您所有细小的提交,但仍然将您的拉取请求作为单个提交呈现给远程仓库。没问题,您可以为此创建一个新分支并从那里发送拉取请求。如果您正在与某人协作在您的功能分支上,并且不想强制推送,这样做也是一个很好的方法。

首先我们将新内容推送到 fork 仓库,以便我们的合作者可以看到它(如果您想将更改保留在本地,这不是必需的)

$ git checkout mynewstuff
$ git push fork

然后我们将为合并(squashed)的拉取请求创建一个新分支

$ 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)

继续处理您的新内容

假设您的拉取请求被拒绝,项目所有者要求您进行一些更改,或者新内容变得更有趣,您需要对其做更多工作。

如果您没有在上面删除它,您可以继续在您的精细分支上工作...

$ git checkout mynewstuff
$ echo yetmore > foo; git commit -am "yet more"
$ git push fork

然后准备好后将更改移到拉取请求分支

$ 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 将两个分支切换到我们想要的位置(如果您愿意,您可以在图形 UI 中执行此操作)

$ 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)

如果我们对拉取请求包含 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/masterfork/mypullrequest 的直接祖先,我知道我的拉取请求将非常容易合并。

总结

希望本教程为您提供了足够的 git 弹药,可以继续并对您喜欢的开源项目进行一些更改,并确信合并将非常容易。请记住,总是存在不止一种方法,git 是一个强大的底层工具,因此您的体验可能会有所不同,并且您可能会发现上述方法的变体更可取甚至必要,这取决于您的更改。

本周 Spring:2011 年 7 月 12 日

工程 | Josh Long | 2011 年 7 月 13 日 | ...

欢迎回到另一期“本周 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…

Grails 2.0 倒计时:静态资源

工程 | Peter Ledbrook | 2011 年 6 月 30 日 | ...

Web 应用程序通常严重依赖于我们所说的静态资源,例如 Javascript、CSS 和图像文件。在 Grails 应用程序中,它们被放入项目的web-app目录中,然后从 HTML 中引用。例如,

<link rel="stylesheet" href="${resource(dir: 'css', file: 'main.css')}" type="text/css">

将创建指向文件web-app/css/main.css的链接。一切都很简单。您甚至可能认为当前的支持对于任何人的需求来说都足够了。您还想做什么?

这是个好问题。答案取决于您的应用程序的复杂性,但让我们从上面的 CSS 链接示例开始。为什么我们必须输入<link rel="..." href=...>?仅从扩展名就可以知道资源是 CSS 文件。我们还知道 CSS 文件应该使用...

本周 Spring:2011 年 6 月 28 日

工程 | Josh Long | 2011 年 6 月 29 日 | ...

欢迎回到另一期“本周 Spring”。

像往常一样,本周有很多很棒的内容。当我们整理这份列表时,我们会在互联网上搜寻有趣的内容,并试图在本周的汇总中以摘要形式呈现给您。我们经常查看的一些资源包括 TwitterSpringSource 博客CloudFoundry.orgTomcat Expert

我们尽量不遗漏任何内容,但我们可能会。如果您知道我们遗漏或认为应该包含的内容,请随时向您的编辑提出任何建议

虽然 SpringSource 在众多会议和行业活动中都有强大的影响力,但 Spring 开发者的首要会议仍然是每年在美国举行的 SpringOne 会议。最终议程的规划正在顺利进行中。请访问SpringOne 2GX 页面查看新闻和活动,并注册参加即将举行的 SpringOne2GX 会议。

    <LI><a href="http://www.springsource.org/spring-social/news/1.0.0.rc1-released">Spring Social 1.0.0.RC1</a…

获取 Spring 新闻通讯

订阅 Spring 新闻通讯,保持联系

订阅

抢先一步

VMware 提供培训和认证,助您加速进步。

了解更多

获取支持

Tanzu Spring 通过一份简单的订阅,提供 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件。

了解更多

即将举行的活动

查看 Spring 社区所有即将举行的活动。

查看所有