在做上一个例子即petstore的例子中,曾出现了应用找不到http service的问题,后来找了半天发现是缺少两个包所致,这两个包为:
org.eclipse.equinox.http.jetty(equinox3.5.1包提供)
org.eclipse.equinox.http.servlet(equinox3.5.1包提供,这个不同于javax.servlet包)
即最终来说,是这两个包负责来初始化一个httpService并放入bundleContext中,并由其他类来监听相应的httpService并与之进行交互。(在下文中,http.jetty表示org.eclipse.equinox.http.jetty,http.servlet表示org.eclipse.equinox.http.servlet,并没有提及到其他引用包)
首先看http.servlet包,经过代码分析,httpService的实现类HttpServiceImpl便在此包中,查看相应的jar,即从启动类org.eclipse.equinox.http.servlet.internal.Activator开始。
1,查看它的start方法,只看到一个进行httpServiceProxy的注册活动startHttpServiceProxy(context);这个方法如下
context = bundleContext;
Object[] proxyServlets = serviceRegistrations.keySet().toArray();
for (int i = 0; i < proxyServlets.length; ++i) {
ServiceRegistration registration = registerHttpService((ProxyServlet) proxyServlets[i]);
serviceRegistrations.put(proxyServlets[i], registration);
}
首先将context静态绑定在当前类中,然后将service注册信息进行重新注册。在这里,serviceRegistrations默认是empty的,所以这段代码在这里执行没有任何效果。 那么,我们来看http.jetty包。
2,查看org.eclipse.equinox.http.jetty.internal.Activator的start方法,其中代码
String autostart = context.getProperty(AUTOSTART);
if ((autostart == null || Boolean.valueOf(autostart).booleanValue()) && !isBundleActivationPolicyUsed(context)) {
Dictionary defaultSettings = createDefaultSettings(context);
httpServerManager.updated(DEFAULT_PID, defaultSettings);
}
这段代码判断是否自动启动一个应用,这个属性值默认为null,所以会进入到启动应用的代码。首先根据相应的参数创建一个默认的启动参数设置,然后由httpServerManager,来进行相应的应用启动, 进入到updated方法。
3,httpServerManager的相应启动应用服务代码
public synchronized void updated(String pid, Dictionary dictionary) throws ConfigurationException {
deleted(pid);
Server server = new Server();
JettyCustomizer customizer = createJettyCustomizer(dictionary);
......
ServletHolder holder = new ServletHolder(new InternalHttpServiceServlet());
holder.setInitOrder(0);
holder.setInitParameter(Constants.SERVICE_VENDOR, "Eclipse.org"); //$NON-NLS-1$
holder.setInitParameter(Constants.SERVICE_DESCRIPTION, "Equinox Jetty-based Http Service"); //$NON-NLS-1$
......
httpContext.addServlet(holder, "/*"); //$NON-NLS-1$
server.addHandler(httpContext);
try {
server.start();
} catch (Exception e) {
throw new ConfigurationException(pid, e.getMessage(), e);
}
servers.put(pid, server);
}
这段代码首先将相应的应用服务删除(具体逻辑略去),然后再创建一个server,并绑定相应的服务处理处理上下文(context),并由context来设置一个相应的具体服务处理的servlet,最后启动这个server.server对象是由Jetty提供的,所以就会最终启动起jetty的一个应用服务起来。但jetty自身并不提供httpService的实现,所以其实现的提供还是得由这两个包提供。
4,这里值得注意的就是所谓的servletHolder,即处理所有具体应用服务的类,它接收一个servlet对象,并将相应的逻辑操作并由这个servlet去执行,来看这个对象的init方法。
public void init(ServletConfig config) throws ServletException {
ServletContext context = config.getServletContext();
contextLoader = (ClassLoader) context.getAttribute(INTERNAL_CONTEXT_CLASSLOADER);
Thread thread = Thread.currentThread();
ClassLoader current = thread.getContextClassLoader();
thread.setContextClassLoader(contextLoader);
try {
httpServiceServlet.init(config);
} finally { thread.setContextClassLoader(current);
}
}
这段代码具体,除进行classLoader的转换之外(这段代码限于知识略去),即调用httpServiceServlet的init方法。而这个httpServiceServlet是用new方法进行声明的,且这个servlet是位于包http.servlet中的!再看相应的service方法,也可以得知,其相应的具体逻辑处理也是并由这个httpServiceServlet来处理的,那么进入这个方法。
5,这个servlet(org.eclipse.equinox.http.servlet.HttpServiceServlet)继承于一个internal的ProxyServlet,进入到其中的init方法。
public void init(ServletConfig config) throws ServletException {
super.init(config);
proxyContext = new ProxyContext(config.getServletContext());
Activator.addProxyServlet(this);
}
这个方法中的最后一行,即将这个servlet添加到Activator中,而这个Activator即是http.servlet的启动类!进入到这个方法。
static synchronized void addProxyServlet(ProxyServlet proxyServlet) {
ServiceRegistration registration = null;
if (context != null)
registration = registerHttpService(proxyServlet);
serviceRegistrations.put(proxyServlet, registration);
}
这个方法会使用这个servlet进行httpService的注册,即registerHttpService方法。
6,之所以是使用这个servlet,原因是在registerHttpService方法中,并没有将servlet与httpService之间进行相应的操作,而只是使用了servlet的servletConfig对象,以取得相应的信息。见代码:
private static ServiceRegistration registerHttpService(ProxyServlet proxyServlet) {
HttpServiceFactory factory = new HttpServiceFactory(proxyServlet);
Dictionary serviceProperties = new Hashtable(2);
ServletConfig config = proxyServlet.getServletConfig();
Enumeration initparameterNames = config.getInitParameterNames();
while (initparameterNames.hasMoreElements()) {
String name = (String) initparameterNames.nextElement();
serviceProperties.put(name, config.getInitParameter(name));
}
if (serviceProperties.get(Constants.SERVICE_VENDOR) == null)
serviceProperties.put(Constants.SERVICE_VENDOR, DEFAULT_SERVICE_VENDOR);
if (serviceProperties.get(Constants.SERVICE_DESCRIPTION) == null)
serviceProperties.put(Constants.SERVICE_DESCRIPTION, DEFAULT_SERVICE_DESCRIPTION);
return context.registerService(HttpService.class.getName(), factory, serviceProperties);
}
这个方法里面,最后用httpServiceFactory对象来进行httpService的注册,即完成了httpService的注册。那么我们来看HttpServiceFactory是如何取得httpService的。
7,httpServiceFactory是一个serviceFactory(org.osgi.framework.ServiceFactory)的实现类,其调用getService方法来取得具体的service实现类。代码如下:
public Object getService(Bundle bundle, ServiceRegistration registration) {
return new HttpServiceImpl(bundle, proxy);
}
这个方法,直接返回一个HttpServiceImpl对象,即最终我们想要的httpService实现类。至此,HttpService的实例化完成,并最终注册到bundleContext中。
在上面的几个步骤中,1,5,6,7步骤是访问http.servlet包中的方法,而2,3,4是访问http.jetty中的方法,两个包一起协同,并终实例化HttpService,以用于我们的实际应用。所以,在用equinox配合springdm作用osgi框架启动时,这两个包是必不可少的包。
分享到:
相关推荐
org.eclipse.equinox.http.helper 有些工程中没有该包 也可以自己从cvs中下载 具体请参照http://blog.csdn.net/hongweigg/article/details/5416067
eclipse中搭建osgi环境需要的两个jar之一:org.eclipse.equinox.http_1.0.0.v20060601a.jar
让OSGi支持JSP和JSF时必须用到的一个Bundle,有用到的可以下载,有耐心的童鞋也可到dev.eclipse.org的CVS开发空间去找找咯。
equinox
equinox-SDK-3.7.zip equinox-SDK-3.7.zip equinox-SDK-3.7.zip equinox-SDK-3.7.zip equinox-SDK-3.7.zip equinox-SDK-3.7.zip
本文将介绍 Equinox 的 ServletBridge 项目,提供一个示例来说明如何使用 ServletBridge,并将简要分析 它的实现方法。 读者将首先了解到如何在 Servlet Container 中嵌入 OSGI,并从文章提供的例子中了了解其工作...
Equinox p2详细图示讲解, RCP中如何实现版本检测,更新
第三部分由原型构建转向实际的产品开发,主要介绍了OSGi和Equinox中用来构建成熟的OSGi应用必不可少的API——服务器端、声明式服务和发布工程,以及如何用它们来解决实践中的一些问题;第四部分呈现了动态性的最佳...
eclipse de osgi框架 equinox-SDK-3.6.1.part1
Equinox
OSGi and Equinox, Creating Highly Modular Java Systems
equinox-SDK-4.18.zip
equinox-all-1.7。Appfuse的缩小版。
org.eclipse.equinox.executable org.eclipse.equinox.launcher org.eclipse.osgi org.eclipse.osgi.tests 另加几篇分析的文章
深入理解OSGi:Equinox原理、应用与最佳实践源代码,同时附带equinox-SDK-3.8源代码。
equinox-SDK-3.8.zip源码包
我实现的《使用Equinox开发OSGI应用程序》全部功能的代码和分发包,工程师基于Eclipse3.3的
基于 equinox 的 OSGI 运行BUNDLE例子,已包含 ECLIPSE 下的OSGI平台包,按步骤运行即可。 当然,设置JAVA_HOME,及BIN环境变量运行JAVAC 就不用说了 ^-^
OSGI标准实现框架equinox的SDK,版本是3.8.2.里面包含equinox的所有插件jar包,适合做OSGI的开发。