使用 SpringSource Slices 构建模块化 Web 应用程序

工程 | Rob Harrop | 2009年6月22日 | ...

更新:添加了 Git 子模块说明。

我过去曾谈到为真正的模块化应用程序提供支持,我很高兴地宣布,您现在可以访问 SpringSource Slices 的早期原型代码。

构建和安装

您可以从我们的 Git 仓库访问源代码

git clone git://git.springsource.org/slices/slices.git
git submodule init
git submodule update

要构建 Slices 的打包版本,只需在 build-slices 目录中运行 ant clean jar package

cd slices/build-slices
ant clean jar package

这将在 target/artifacts 中生成一个 zip 文件,其中包含 Slices 子系统,然后可以将其安装到 dm Server 2.0 上

安装 Slices 只是将新的子系统添加到 dm Server,然后更新 dmServer 的配置文件以启动新的子系统。Slices 应该适用于任何最新的 dm Server 2.0 快照版本。我这里使用的是 2.0.0.CI-R326-B274,我已经下载并解压缩到我的桌面

 unzip target/artifacts/springsource-slices-BUILD-20090622083953.zip -d ~/Desktop/springsource-dm-server-2.0.0.CI-R326-B274

接下来,必须更新 dm Server 的 kernel.properties 配置以包含新的 slices 子系统。打开 dm Server 安装的 config/kernel.properties 文件,并编辑配置文件配置部分以列出 slices 子系统并为配置文件指定一个合适的名称(我将其命名为 slices)

#######################
# Profile Configuration
#######################
profile.name=slices
profile.subsystems=	com.springsource.server.web,com.springsource.osgi.slices
profile.optionalSubsystems=

保存更新后的文件,你就可以尝试 Slices 示例应用程序了。

试用示例应用程序

Slices 仓库包含一个 Spring 3 PetClinic 示例版本,我们随着 Slices 新功能的增加不断地对其进行增强和改进。

在使用示例之前,必须将其依赖项添加到 dm Server 安装中。依赖项列在示例的 dependencies.txt 文件中。将列出的每个依赖项下载到安装的 repository/bundles/usr 目录。接下来,使用 -clean 启动选项启动 dm Server

./bin/startup.sh -clean

现在是构建和部署示例的时候了。进入 slices/samples/slices-petclinic/com.springsource.slices.petclinic.host 目录并运行 ant clean jar

cd samples/slices-petclinic/com.springsource.slices.petclinic.host
ant clean jar

然后可以通过将生成的 war 包复制到 dm Server 的 pickup 目录来部署主机

 cp target/artifacts/com.springsource.slices.petclinic.host.war ~/Desktop/springsource-dm-server-2.0.0.CI-R326-B274/pickup/

现在应该可以从 https://:8080/petclinic 访问主机了

petclinic-no-slices

接下来,进入 slices/samples/slices-petclinic/com.springsource.slices.petclinic.appointments 目录并运行 ant clean jar 来构建 appointments slice

cd samples/slices-petclinic/com.springsource.slices.petclinic.appointments
ant clean jar

现在可以通过将生成的 war 包复制到 dm Server 的 pickup 目录来部署 slice

cp target/artifacts/com.springsource.slices.petclinic.appointments.war  ~/Desktop/springsource-dm-server-2.0.0.CI-R326-B274/pickup/

刷新 https://:8080/petclinic,它现在将反映 appointments slice 的存在,并带有一个新的 Appointments 链接

petclinic-appointments-slice

如果您愿意,现在可以从 pickup 目录中删除 appointments war 包,以查看 slice 再次消失。

Slices 应用程序的剖析

使用 Slices,您可以从多个 OSGi 捆绑包构建一个 Web 应用程序,每个捆绑包都为应用程序 URL 空间的独立子部分提供内容。Slices 应用程序以父/子结构排列,每个应用程序最多有一个父级(称为主机),以及零个或多个子级(称为 slices)。我们正在开发一个简单的 Slices 示例,它看起来像这样

slice-anatomy

主机内部

petclinic.host 捆绑包包含所有共享内容,例如图像和 CSS,以及用于提供主页的控制器和 JSP。主机捆绑包只是一个符合 RFC66 规范的 Web 捆绑包,在其 web.xml 中配置了 SliceHostFilter。下面的代码片段显示了来自 petclinic.host 捆绑包的 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
	
    <filter>
    	<filter-name>host-filter</filter-name>
    	<filter-class>com.springsource.osgi.slices.core.SliceHostFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>host-filter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

	<!-- Enables clean URLs with JSP views e.g. /welcome instead of /app/welcome -->
	<filter>
		<filter-name>UrlRewriteFilter</filter-name>
		<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
	</filter>

	<filter-mapping>
		<filter-name>UrlRewriteFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
		
	<!-- Handles all requests into the application -->
	<servlet>
		<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>
				/WEB-INF/spring/*.xml
			</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
		
	<!-- Maps all /app requests to the DispatcherServlet for handling -->
	<servlet-mapping>
		<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
		<url-pattern>/app/*</url-pattern>
	</servlet-mapping>

  	<!-- Serves static resource content from the webapp root & .jar files such as spring-js.jar -->
	<servlet>
		<servlet-name>Resources Servlet</servlet-name>
		<servlet-class>org.springframework.js.resource.ResourceServlet</servlet-class>
		<load-on-startup>0</load-on-startup>
	</servlet>
		
	<!-- Map all /resources requests to the Resource Servlet for handling -->
	<servlet-mapping>
		<servlet-name>Resources Servlet</servlet-name>
		<url-pattern>/resources/*</url-pattern>
	</servlet-mapping>	
	
</web-app>

正如您所看到的,主机可以有任何正常的 servlet 和过滤器映射,但它需要 SliceHostFilter 才能将请求路由到其 slices。

Slice 内部

slice 是一个捆绑包,其外观和功能类似于标准 RFC66 Web 捆绑包,只不过它没有自己的 ServletContext。相反,slice 在其主机的 ServletContext 下运行。

Slices 的主要设计目标之一是确保 slice 开发与标准 Web 应用程序开发尽可能相似。为此,您可以使用 web.xml 以与为任何应用程序创建 Web 内容完全相同的方式创建 slice Web 内容。这是来自 petclinic.appointments 捆绑包的 web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

	<!-- Handles all requests into the application -->
	<servlet>
		<servlet-name>appointments</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>		
		<load-on-startup>1</load-on-startup>
	</servlet>
		
	<!-- Maps all /app requests to the DispatcherServlet for handling -->
	<servlet-mapping>
		<servlet-name>appointments</servlet-name>
		<url-pattern>/app/*</url-pattern>
	</servlet-mapping>
	
</web-app>

appointments slice 只是委托给 Spring DispatcherServlet。Spring MVC 可以在 slice 中正常使用。

slice 可以通过简单地引用 slice 本身不存在的资源名称来访问主机捆绑包中的资源。如果 slice 想要访问主机中的资源,即使它自己有一个同名资源,它也可以使用 host: 前缀来访问

ServletContext context =  getServletContext();
context.getResource("host:/WEB-INF/some.config.xml");

slice 需要定义它想要附加到的主机,并使用 Slice-Host 清单头来完成。 Slice-ContextPath 头定义了 slice 处理的 URL 部分

Bundle-SymbolicName: petclininc.appointments
Slice-Host: petclinic.host;version="[1.0, 2.0)"
Slice-ContextPath: /appointments

Slice 生命周期

主机可以在没有附加任何相应 slice 的情况下运行。当与主机匹配的 slice 安装到服务器中时,该 slice 将附加到主机。此时,与新附加的 slice 的 Slice-ContextPath 匹配的主机 URL 部分的子部分将路由到该 slice。

当 slice 被卸载时,路由到 slice 的 URL 空间部分现在将直接路由到主机。通过这种方式,您可以在主机中创建内容来处理缺失的 slices。

今天我可以在 Slice 中做什么?

截至本文撰写时,Slices 代码库支持 Slice 中的以下功能

  • Servlets 和 servlet 映射
  • JSP
  • Spring MVC
  • Slice 本地会话
  • 自动回退到应用程序范围的会话
  • 通过 ServletContext 进行 slice 本地资源查找
  • 自动回退到主机中的资源查找
  • 使用 host: 显式主机资源查找

下一步是什么?

我们正在为 Slices 开发许多有趣的新功能,包括

  • slices 中的过滤器和过滤器映射
  • slices 中的监听器
  • UI 组合框架。您可以在 Petclinic 示例中看到一种手动方法
  • Tiles 2 集成
  • 完整的示例应用程序
  • SpringSource Tool Suite 支持

如果您有任何功能建议或发现错误,请随时 在我们的 JIRA 上提出问题。

如果您想密切关注进度,可以关注我们的 Git 仓库和我们的 #dmserver Twitter 标签。

获取 Spring 新闻通讯

通过 Spring 新闻通讯保持联系

订阅

领先一步

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

了解更多

获得支持

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

了解更多

即将举行的活动

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

查看所有