RabbitMQ:在 Cloud Foundry 上启用 Grails 全文搜索

工程技术 | Peter Ledbrook | 2011 年 8 月 29 日 | ...

在我的关于 Grails 和 Cloud Foundry 的第二篇博客中,我介绍了一个可以在 CloudFoundry.com 上托管的 Grails Twitter 示例变体。当时我提到,使用 Searchable 插件进行全文搜索会限制你只能使用单个应用实例,因为搜索索引对于每个实例都是唯一的。换句话说,根据你的浏览器被路由到哪个应用实例,你可能会很容易得到不同的搜索结果。

我还说过,解决这个问题的一个选择是跨实例同步搜索索引。但这听起来并…

Android 应用中的整洁代码

工程技术 | Roy Clarkson | 2011 年 8 月 26 日 | ...

假设有一天早上你醒来,心想:“嘿,我今天要做一个 Android 应用。”首先,好主意!截至六月底,每天有 50 万台 Android 设备被激活,甚至超过了 iPhone。这意味着你的应用拥有庞大的潜在用户群。此外,Android 是用 Java 构建的。这可能看起来没什么大不了,但我已经在 iOS 平台上用 Objective-C 开发了几年,虽然我现在用得很顺手,但 iOS SDK 的学习曲线比我在 Android 上遇到的要陡峭。刚开始使用 Android SDK 时,Android 给我的感觉更易于入门。话虽如此,Android 与你过去构建过的任何其他 Java 应用还是有一些明显的区别,我将在第一部分讨论其中的一些。

随着时间的推移,你完成了第一个应用,并将其提交到了 Android Market。恭喜你,你的朋友们都在下载你的应用并转发推文。现在是时候开始你的第二个应用了。你花了几天时间,突然意识到你开始重复使用第一个应用中的代码,这本身并不是一件坏事。代码重用是有价值的。但是你注意到有很多样板代码往往会重复出现,这会分散你专注于业务逻辑的注意力。幸运的是,有一些方法可以对此进行改进。

在这篇博文中,我将概述 Android 及其应用生命周期,并讨论框架带来的一些限制。我还会回顾一些技巧和第三方项目,它们可以帮助你整理 Android 代码,并专注于你想通过应用实现的目标。

Android 概览

让我们先简要介绍一下 Android 的工作原理。Android 应用程序 (app) 使用 Java 构建,并编译成 class 文件。然后,这些 class 文件被编译成 Dalvik Executable (DEX) 格式,以便它们可以在 Android 使用的 Dalvik 虚拟机上运行。转换成 DEX 格式后,class 文件被打包成 Android Package (APK) 用于分发到设备。由于使用了 DEX 格式,Dalvik VM 不是一个真正的 Java 虚拟机,因为它不直接运行 Java 字节码。此外,Dalvik VM 的核心类库是基于 Apache Harmony 项目的一个子集。这意味着你在 Java SE 中习惯使用的许多类和方法是可用的,但肯定不是全部。我发现 Android 开发者网站上的 API 参考是查阅这些差异的宝贵资源。

默认情况下,每个 Android 应用程序都会被 Android 操作系统分配一个唯一的 Linux 用户 ID。当系统启动时,应用程序在其自己的 Linux 进程中运行,并在其自己的虚拟机 (VM) 中运行。系统在需要时管理此进程的启动和关闭。正如你所猜,这意味着每个应用程序与其他正在运行的应用程序是隔离运行的。安装时,应用程序可以请求访问硬件功能或与其他应用程序交互的权限。用户选择授予应用这些权限或不安装它。应用所需或请求的权限在其 Android Manifest 文件中定义。这是一个 XML 文件,列出了应用的所有组件以及这些组件的任何设置。应用程序组件的四种类型是 activitiesservicescontent providersbroadcast receivers。出于本文的目的,我将重点介绍 activities。

activities 基本上代表 Android 应用程序的一个屏幕。例如,一个 Twitter 应用可能有一个登录屏幕、一个包含推文列表的屏幕以及一个用于撰写新推文的屏幕。这些屏幕中的每一个都代表应用程序内不同的 activity。作为开发者,你永远不会自己实例化 activity 对象。activities 通过发送一个称为 Intent 的异步消息来激活,如下例所示。


startActivity(new Intent(context, HomeActivity.class));

当调用 startActivity(Intent intent) 时,系统要么创建一个新实例,要么重用一个现有实例,以便向用户显示 activity。重要的一点是,系统控制应用程序和每个 activity 的启动、停止、创建和销毁。如果你想与这个过程进行交互,那么应用程序和 activity 类提供了用于不同生命周期事件的方法,你可以在子类中重写这些方法。

依赖注入

Spring Android 项目最近发布了其第四个里程碑版本。随着这个版本的发布,我们继续改进了对 Android 的 RestTemplateSpring Social 支持,这简化了发出 RESTful HTTP 请求和访问由 OAuth 保护的 REST API 的过程。虽然我们认为这些是对 Android 开发的有价值的补充,但一些开发者提出了关于 Spring Android 中是否可能支持依赖注入的问题,因为你可能知道,Spring Framework 已经提供了一个流行的控制反转 (IOC) 容器,用于在企业级 Java 应用中实现依赖注入。在 Spring Android 的早期规划阶段,依赖注入支持被认为是项目包含的潜在候选。当时,还不清楚这种支持会涉及什么,以及如何实现。因此,我开始研究和调查在 Android 中进行依赖注入的可能方法和限制。

那么,什么是依赖注入?如果你问两个不同的开发者,你可能会得到两个不同的答案。你可能会听到关于 IOC、XML 文件、注解或其他实现细节。实际上,依赖注入只是一种减少耦合的技术,它通过将对象工作所需的内容提供给它,而不是让对象主动获取其环境中的内容。这听起来很简单,你可能会想,这通过类的构造函数和 setter 方法就可以实现,这完全正确。然而,回想一下上面的概览部分,Android 系统驱动着应用的生命周期,所以我们实现这种方式的方法是有限的。

Android 方式

不使用任何第三方库,将依赖项传递给 Activity 是相当容易的。如前所述,系统会创建应用程序实例。因此,通过扩展 application,你可以有效地创建一个单例依赖项实例,然后应用程序中的任何 activity 都可以访问它。


public class MainApplication extends Application  {

    private MyService service;

    @Override
    public void onCreate() {
        super.onCreate();
        service = new MyServiceImpl();
    }

    public MyService getMyService() {
        return this.service;
    }
}

activity 类有一个名为 getApplication() 的方法,它返回拥有该 activity 的 application 对象的引用。我们只需将其转换为 MainApplication,就可以访问 MyService 的 getter 方法。当然,现在 activity 必须“知道”这个 application,这看起来可能是一个缺点。但记住,activity 本来就知道它的 application。这个方法是内置的。


public class MainActivity extends Activity  {

    private MyService service;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        MainApplication app = (MainApplication…

本周的 Spring:2011 年 8 月 23 日

工程技术 | Josh Long | 2011 年 8 月 24 日 | ...

欢迎阅读又一期《本周的 Spring》。随着下周的 VMworld 2011 临近,一切都在快速推进。我邀请所有与会者参观 VMWorld Spring 展位的专家技术人员。如果你阅读了这周的总结,请告诉我。本周有很多内容要谈,让我们开始吧!

    <li>The preliminary session schedule has been published for <a href="http://www.springone2gx.com">SpringOne 2GX 2011</a>. This year's show is going to be another fantastic mix of deep technical content, cutting edge development and the absolute best place to learn about everything in the Spring universe. Be sure to <a href="http://springone2gx.com/conference/chicago/2011/10/register">register now</a>!</li>
    
    <LI> <a href="http://static.springsource.org/spring/docs/3.0.6.RELEASE/changelog.txt">Spring 3.0.6's was just released!</a>   		 
    	 This release addresses over 50 minor issues and includes…

适用于 Spring 开发者的 Micro Cloud Foundry

工程技术 | Josh Long | 2011 年 8 月 24 日 | ...

今天,VMware 团队发布了 Micro Cloud Foundry,这是一个流行开源平台即服务 (PaaS) 的完整本地版本,它允许开发者在其 Mac 或 PC 上运行功能齐全的云。使用 Micro Cloud Foundry,开发者可以在本地构建端到端的云应用,无需配置中间件的麻烦,同时保留部署地点的选择权以及无需更改任何代码即可扩展应用的能力。

Micro Cloud Foundry 当然支持 Spring 和 Java,但也提供了 Scala、Node.js 和 Ruby 的运行时环境,这样你就可以释放你内心的多语言程序员天赋!Micro Cloud Foundry 还提供了许多服务,如 MongoDB、MySQL 和 Redis,这些服务可以直接使用,无需进行大量的安装和配置。凭借内置的动态 DNS 支持,开发者可以在任何地方运行他们的 Micro Cloud Foundry,无论是在家、办公室还是咖啡馆,无需任何重新配置。在 Micro Cloud Foundry 上创建和测试你的应用后,你可以轻松地部署你的…

从 Grails 使用 Micro Cloud Foundry

工程技术 | Peter Ledbrook | 2011 年 8 月 24 日 | ...

回到四月,VMware 向世界介绍了 Cloud Foundry,随之而来的是面向 Grails 开发者的超级简单的应用程序部署。几个月后,另一块拼图到位了:Micro Cloud Foundry。你现在可以拥有自己的 Cloud Foundry 实例用于测试或任何其他用例。当然,从 Grails 使用它也非常容易。

那么什么是 Micro Cloud Foundry?以下截屏视频简要介绍了该产品,然后带你完成下载、安装和配置过程。最后,你将看到如何…话题,所以我们开始吧!

Grails 2.0 倒计时:数据库迁移

工程技术 | Peter Ledbrook | 2011 年 8 月 17 日 | ...

Grails 的众多出色特性之一是它可以根据你的领域模型为你自动创建数据库 schema。诚然,这是 Grails 使用的 Hibernate 的一个特性,但它仍然可以帮助你非常快速地开始构建数据库驱动的 Web 应用,而无需担心数据库 schema。

一旦你的应用进入生产环境会发生什么?在开发过程中,服务器运行期间丢失数据不是大问题。但你不能在生产环境中轻易删除数据库。因此,这排除了dbCreate数据源的 “create” 和 “create-drop” 值…关于这周有很多内容要谈,所以我们开始吧!

云中聊天:第一部分

工程技术 | Mark Fisher | 2011 年 8 月 16 日 | ...

上周,Cloud Foundry 上的 RabbitMQ 服务可用性已宣布。现在,任何在 Cloud Foundry 上运行的应用都可以通过 RabbitMQ 代理发送和接收消息,该代理可以通过单个命令(例如 'vmc create-service rabbitmq')作为服务进行预配。消息服务的实例可以在应用之间共享,并且由于 RabbitMQ 是基于协议的代理,这些应用甚至可以用不同的语言编写。因此,对于那些对在云中运行的模块化、多语言、事件驱动的应用感兴趣的人来说,这是一个令人兴奋的消息。我将…

在不使用完整 Java EE 的情况下配置 Spring 和 JTA

工程技术 | Josh Long | 2011 年 8 月 15 日 | ...

Spring 通过其 PlatformTransactionManager 接口及其实现层次结构提供了丰富的事务管理支持。Spring 的事务支持为众多 API 的事务语义提供了一致的接口。广义上,事务可以分为两类:本地事务和全局事务。本地事务是仅影响一个事务资源的事务。通常,这些资源都有自己的事务 API,即使事务的概念没有被明确地体现出来。通常它以会话的概念形式出现,一个…

FactoryBean 之外

工程技术 | Josh Long | 2011 年 8 月 10 日 | ...

我之前的文章中,我介绍了基本的 FactoryBean 是什么。虽然 FactoryBean 很重要——了解它们的作用可以帮助你更有效地掌握框架——但从 Spring 3.0 和即将发布的 Spring 3.1 开始,它们在很大程度上不再是推荐的方法。

FactoryBean 的全部意义在于隐藏对象的构建过程——要么因为对象非常复杂,要么因为它不能简单地使用 Spring 容器惯用的以构造函数为中心的方式实例化(也许需要查找?也许需要一个静态注册方法?)。Spring 还支持 XML 格式中的 factory-method 属性。Java 配置方法提供了一种概念上类似(实际上结果相同)的替代方案,但它具有更简洁、类型安全的特点。

Spring 3.0 引入了 Java 配置,它允许你使用 Java 定义 bean。例如,要在 XML 中向 Spring 注册一个普通的 javax.sql.DataSource,你很可能会将敏感的配置信息(如数据库密码)委托给属性文件,并使用 Spring 来实例化 javax.sql.DataSource,如下所示


<beans ...>
	<context:property-placeholder location = "ds.properties" />

	<bean id = "ds" class = "a.b.c.MySqlDataSource">
	  <property name = "user" value = "${ds.user}"/>
	  <property name = "password" value = "${ds.password}"/>
	</bean>
</beans>

这是一个简单的 bean,很自然地转换为 Java 配置。它看起来像这样

 
import a.b.c.* ;
	
@Configuration 
@PropertySource("ds.properties") 
public class MyConfiguration { 
    @Inject private Environment env ; 
	
    @Bean public MySqlDataSource ds(){ 
        MySqlDataSource ds = new MySqlDataSource () ; 
        ds.setUser( env.getProperty("ds.user") );
        ds.setPassword( env.getProperty("ds.password…

什么是 FactoryBean?

工程技术 | Josh Long | 2011 年 8 月 9 日 | ...

在这篇博文中,我将介绍 Spring 的 org.springframework.beans.factory.FactoryBean<T> 接口。此接口的定义如下


public interface FactoryBean<T> {
  T getObject() throws Exception;
  Class<T> getObjectType();
  boolean isSingleton();
}

FactoryBean 是一种模式,用于在类中封装有趣的对象的构建逻辑。例如,它可能用于以可重用方式编码复杂对象图的构建。通常这用于构建具有许多依赖项的复杂对象。当构建逻辑本身高度易变且依赖于配置时,也可能使用它。FactoryBean 也有助于 Spring 构建它本身不易构建的对象。例如,为了注入从 JNDI 获取的 bean 的引用,必须首先获取该引用。你可以使用 JndiFactoryBean 以一致的方式获取此引用。你可以将 FactoryBeangetObject() 方法的结果注入到任何其他属性中。

假设你有一个 Person 类,其定义如下


public class Person { 
 private Car car ;
 private void setCar(Car car){ this.car = car;  }	
}

以及一个 FactoryBean,其定义如下


public class MyCarFactoryBean implements FactoryBean<Car>{
  private String make; 
  private int year ;

  public void setMake(String m){ this.make =m ; }

  public void setYear(int y){ this.year = y; }

  public Car getObject(){ 
    // wouldn't be a very useful FactoryBean 
    // if we could simply instantiate the object…

获取 Spring 新闻通讯

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

订阅

领先一步

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

了解更多

获取支持

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

了解更多

即将举办的活动

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

查看全部