在做上一个例子即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框架启动时,这两个包是必不可少的包。
分享到:
相关推荐
在Java世界中,OSGi(Open Service Gateway Initiative)框架提供了一种强大的模块化系统构建方式,使得应用程序可以被分解为独立、互相依赖的服务。Equinox是Eclipse基金会提供的一个OSGi实现,它允许开发者创建...
Spring框架是Java企业级应用中广泛使用的依赖注入(DI)和面向切面编程(AOP)框架。Spring DM是Spring框架的一个扩展,专门为OSGi环境设计。它允许开发者在OSGi容器中充分利用Spring的功能,例如配置管理、事务处理...
在Struts程序中集成Spring,可以通过Spring管理Struts中的各种组件,如Action、Service和DAO等。 6. **概述**: - 本教程将通过一个名为"MyUsers"的示例程序来展示如何使用Spring框架进行开发。该程序是一个典型的...
在OSGi框架中,Equinox是Eclipse基金会提供的一个实现,它是OSGi规范的主要实现之一,广泛应用于服务器端开发。Equinox提供了一个强大的、可扩展的运行时环境,支持动态模块加载和卸载,使得开发者可以灵活地更新和...
下面我们将详细探讨如何在IntelliJ IDEA中创建和运行一个简单的OSGi HelloWorld程序。 **1. OSGi基础知识** OSGi的核心概念包括: - **Bundle**:是OSGi的基本模块单位,类似于Java的JAR文件,但包含额外的元数据...
在本教程中,我们将学习如何搭建一个基于OSGi的开发环境,并通过Equinox——一个流行的OSGi实现,创建并运行一个简单的"Hello World"程序。 **1. Equinox介绍** Equinox是IBM贡献给Eclipse Foundation的OSGi核心...
标题中的“OSGi Hibernate”指的是将Java的OSGi(Open Service Gateway Initiative)框架与Hibernate ORM(Object-Relational Mapping)工具进行集成的技术实践。OSGi是一种模块化系统,它允许在运行时动态地发现、...
- **选择OSGi实现**:如Apache Felix、Equinox等,它们提供了运行时环境。 - **集成Spring**:引入Spring OSGi相关的库,如spring-osgi-core、spring-osgi-io等。 - **配置Bundle**:创建Manifest.MF文件,声明...
- **示例代码**:在 `service.xml` 文件中,可以进一步使用 Spring 的注解,如 `@Component` 和 `@Service`,来替代原有的 `<provide>` 标签。 通过以上步骤,我们不仅实现了 OSGi Bundle 的基本功能,还成功地将 ...
标题中的"osgi_spring_dm_jr"可能是指OSGi(Open Service Gateway Initiative)框架下,Spring Dynamic Modules(Spring DM)的Java Runtime环境相关的知识。OSGi是一种模块化系统,用于构建可升级、可扩展和可配置...
Spring Bundle 是一个专门为基于OSGi(Open Service Gateway Initiative)架构的Java应用程序设计的框架,它使得在OSGi环境中管理和部署Spring应用变得更加简单。OSGi是一种模块化系统,它允许Java应用按需加载和...
Spring Dynamic Modules是Spring框架的一个扩展,它允许开发者以模块化的方式构建应用,尤其是在OSGi(Open Service Gateway Initiative)容器中。OSGi是一种Java模块化系统,提供了动态部署、版本管理和服务导向的...
SpringDM(Spring Dynamic Modules)是Spring框架的一个扩展,专为在OSGi(Open Service Gateway Initiative)环境中运行应用程序而设计。OSGi是一种模块化系统,它允许Java应用程序以模块化的形式进行构建、部署和...
Struts处理MVC模式中的视图和控制,Spring负责依赖注入和事务管理,Hibernate则作为ORM工具处理数据库交互。 **Spring-DM**(Spring Dynamic Modules)是SpringSource推出的一个框架,它的目标是简化在OSGi环境中...
Spring OSGi 是一个将流行的Spring框架与OSGi(Open Service Gateway Initiative)规范结合的开源项目,它允许开发者在OSGi环境中充分利用Spring的功能。OSGi是一种模块化系统,旨在创建可伸缩、灵活且可维护的Java...
它允许开发者利用Spring的依赖注入(DI)和面向切面编程(AOP)特性在OSGi环境中编写和管理服务。Spring DM的主要目标是简化OSGi服务的生命周期管理和配置,使得开发者能够像在非OSGi环境中一样轻松地使用Spring。 ...