Spring DM 1.1.x 最引人注目的特性莫過於原生支援 Web 應用部署。經過實際測試,這項功能不僅運作流暢,甚至在某些方面優於 Spring DM Server——至少在可移植性上佔據優勢,能夠在多個支援 Spring DM 的 OSGi 平台上運行,而 Spring DM Server 並未提供更多企業級應用支援。
成功配置的關鍵在於正確佈署以下 Bundles(均可在 Spring DM 1.1.2 發布包中找到,啟動層級設為 2):
0 ACTIVE system.bundle_3.2.2.R32x_v20070118
1 ACTIVE com.springsource.slf4j.api_1.5.0
2 RESOLVED org.springframework.osgi.jetty.web.extender.fragment.osgi_1.0.0 (Master=46)
3 ACTIVE org.springframework.bundle.osgi.extender_1.0.1.v200803070100
4 ACTIVE org.springframework.bundle.spring.core_2.5.5
5 ACTIVE org.springframework.bundle.spring.web_2.5.5
6 ACTIVE com.springsource.org.objectweb.asm_2.2.3
7 RESOLVED osgi_log_config_1.0.0 (Master=36)
8 ACTIVE org.springframework.bundle.osgi.core_1.0.1.v200803070100
9 ACTIVE com.springsource.slf4j.log4j_1.5.0
10 ACTIVE org.springframework.bundle.spring_2.5.2.v200803070100
11 ACTIVE org.springframework.bundle.spring.context_2.5.5
12 ACTIVE javax.servlet_2.4.0.v200706111738
13 ACTIVE org.springframework.osgi.servlet-api.osgi_2.5.0.SNAPSHOT
14 ACTIVE com.springsource.net.sf.cglib_2.1.3
15 ACTIVE org.springframework.bundle.spring.beans_2.5.5
16 ACTIVE javax.servlet.jsp_2.0.0.v200706191603
18 ACTIVE org.springframework.osgi.jetty.start.osgi_1.0.0
19 ACTIVE org.springframework.bundle.osgi.io_1.0.1.v200803070100
20 ACTIVE org.aopalliance_1.0.0
21 ACTIVE org.springframework.bundle.spring.context.support_2.5.5
23 ACTIVE com.springsource.org.aopalliance_1.0.0
24 ACTIVE org.springframework.bundle.spring.aop_2.5.5
25 ACTIVE com.springsource.slf4j.org.apache.commons.logging_1.5.0
30 ACTIVE org.objectweb.asm_2.2.3
33 ACTIVE org.mortbay.jetty.server_6.1.9
35 ACTIVE org.mortbay.jetty.util_6.1.9
36 ACTIVE org.springframework.osgi.log4j.osgi_1.2.15.SNAPSHOT (Fragments=7)
37 ACTIVE org.mortbay.jetty_5.1.11.v200706111724
43 ACTIVE org.springframework.bundle.osgi.extender_1.1.2
44 ACTIVE org.springframework.bundle.osgi.io_1.1.2
45 ACTIVE org.springframework.bundle.osgi.web_1.1.2
46 ACTIVE org.springframework.bundle.osgi.web.extender_1.1.2 (Fragments=2)
47 ACTIVE org.springframework.bundle.osgi.core_1.1.2
需額外加入提供 log4j.properties 的 Bundle,具體做法可參考「Spring OSGi 快速入門」教學。
OSGi Web 應用結構與傳統 Web 應用大同小異,僅需增加 OSGi 專屬配置:
META-INF/
MANIFEST.MF
WEB-INF/
classes/
lib/
web.xml
applicationContext.xml
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Osgi_web_app Plug-in
Bundle-SymbolicName: osgi_web_app
Bundle-Version: 1.0.0
Bundle-Vendor: ccsoft
Import-Package: javax.servlet,
javax.servlet.http,
javax.servlet.resources;version="2.4.0",
org.ccsoft.service,
org.springframework.osgi.web.context.support;version="1.1.2",
org.springframework.web.context,
org.springframework.web.context.support
Bundle-ClassPath: WEB-INF/classes/,
.
Require-Bundle: org.springframework.bundle.osgi.core,
org.springframework.bundle.osgi.io,
org.springframework.bundle.spring.beans,
org.springframework.bundle.spring.context,
org.springframework.bundle.spring.core
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="https://java.sun.com/xml/ns/j2ee"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://java.sun.com/xml/ns/j2ee https://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<display-name>Simple Osgi WebApp Bundle</display-name>
<description>Simple OSGi War</description>
<context-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>org.ccsoft.web.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/servlet</url-pattern>
</servlet-mapping>
</web-app>
關鍵在於指定 contextClass 為 OsgiBundleXmlWebApplicationContext,使 Spring DM 能夠接管 Web 應用的上下文初始化。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://www.springframework.org/schema/beans"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns:osgi="https://www.springframework.org/schema/osgi"
xsi:schemaLocation="https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
https://www.springframework.org/schema/osgi https://www.springframework.org/schema/osgi/spring-osgi.xsd">
<osgi:reference id="HelloServiceOsgi" interface="org.ccsoft.service.SpeakService"/>
</beans>
透過 <osgi:reference> 即可引用其他 Bundle 發布的 OSGi 服務。
WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(req.getSession().getServletContext());
SpeakService ss = (SpeakService) ctx.getBean("HelloServiceOsgi");
用法與傳統 Spring Web 開發完全一致,降低學習曲線。
完成上述配置後,即可基於 Spring DM 開發可移植的 OSGi Web 應用。