`
Fly_m
  • 浏览: 259620 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

equinox中http service的详细注入过程

    博客分类:
  • osgi
阅读更多

    在做上一个例子即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框架启动时,这两个包是必不可少的包。

分享到:
评论
1 楼 xiaoasha 2014-10-07  
   终于找到解决方法了

相关推荐

    《osgi与equinox 创建高度模块化的java系统》第6章DS代码

    在Java世界中,OSGi(Open Service Gateway Initiative)框架提供了一种强大的模块化系统构建方式,使得应用程序可以被分解为独立、互相依赖的服务。Equinox是Eclipse基金会提供的一个OSGi实现,它允许开发者创建...

    Apress - Pro Spring Dynamic Modules for OSGi Service Platforms 2009

    Spring框架是Java企业级应用中广泛使用的依赖注入(DI)和面向切面编程(AOP)框架。Spring DM是Spring框架的一个扩展,专门为OSGi环境设计。它允许开发者在OSGi容器中充分利用Spring的功能,例如配置管理、事务处理...

    Spring基础教程

    在Struts程序中集成Spring,可以通过Spring管理Struts中的各种组件,如Action、Service和DAO等。 6. **概述**: - 本教程将通过一个名为"MyUsers"的示例程序来展示如何使用Spring框架进行开发。该程序是一个典型的...

    OSGi Web示例工程

    在OSGi框架中,Equinox是Eclipse基金会提供的一个实现,它是OSGi规范的主要实现之一,广泛应用于服务器端开发。Equinox提供了一个强大的、可扩展的运行时环境,支持动态模块加载和卸载,使得开发者可以灵活地更新和...

    IntelliJ IDEA OSGI helloworld

    下面我们将详细探讨如何在IntelliJ IDEA中创建和运行一个简单的OSGi HelloWorld程序。 **1. OSGi基础知识** OSGi的核心概念包括: - **Bundle**:是OSGi的基本模块单位,类似于Java的JAR文件,但包含额外的元数据...

    OSGi开发环境建立和Hello World

    在本教程中,我们将学习如何搭建一个基于OSGi的开发环境,并通过Equinox——一个流行的OSGi实现,创建并运行一个简单的"Hello World"程序。 **1. Equinox介绍** Equinox是IBM贡献给Eclipse Foundation的OSGi核心...

    osgi hibernate

    标题中的“OSGi Hibernate”指的是将Java的OSGi(Open Service Gateway Initiative)框架与Hibernate ORM(Object-Relational Mapping)工具进行集成的技术实践。OSGi是一种模块化系统,它允许在运行时动态地发现、...

    Spring OSGI 快速入门中文教程

    - **选择OSGi实现**:如Apache Felix、Equinox等,它们提供了运行时环境。 - **集成Spring**:引入Spring OSGi相关的库,如spring-osgi-core、spring-osgi-io等。 - **配置Bundle**:创建Manifest.MF文件,声明...

    OSGI入门和整合Spring

    - **示例代码**:在 `service.xml` 文件中,可以进一步使用 Spring 的注解,如 `@Component` 和 `@Service`,来替代原有的 `&lt;provide&gt;` 标签。 通过以上步骤,我们不仅实现了 OSGi Bundle 的基本功能,还成功地将 ...

    osgi_spring_dm_jr

    标题中的"osgi_spring_dm_jr"可能是指OSGi(Open Service Gateway Initiative)框架下,Spring Dynamic Modules(Spring DM)的Java Runtime环境相关的知识。OSGi是一种模块化系统,用于构建可升级、可扩展和可配置...

    springBundle常用包

    Spring Bundle 是一个专门为基于OSGi(Open Service Gateway Initiative)架构的Java应用程序设计的框架,它使得在OSGi环境中管理和部署Spring应用变得更加简单。OSGi是一种模块化系统,它允许Java应用按需加载和...

    Spring Dynamic Modules Reference Guide中文版

    Spring Dynamic Modules是Spring框架的一个扩展,它允许开发者以模块化的方式构建应用,尤其是在OSGi(Open Service Gateway Initiative)容器中。OSGi是一种Java模块化系统,提供了动态部署、版本管理和服务导向的...

    SpringDM Runtime

    SpringDM(Spring Dynamic Modules)是Spring框架的一个扩展,专为在OSGi(Open Service Gateway Initiative)环境中运行应用程序而设计。OSGi是一种模块化系统,它允许Java应用程序以模块化的形式进行构建、部署和...

    基于OSGi的Web应用开发系列(全).pdf

    Struts处理MVC模式中的视图和控制,Spring负责依赖注入和事务管理,Hibernate则作为ORM工具处理数据库交互。 **Spring-DM**(Spring Dynamic Modules)是SpringSource推出的一个框架,它的目标是简化在OSGi环境中...

    Spring OSGi 入门.rar

    Spring OSGi 是一个将流行的Spring框架与OSGi(Open Service Gateway Initiative)规范结合的开源项目,它允许开发者在OSGi环境中充分利用Spring的功能。OSGi是一种模块化系统,旨在创建可伸缩、灵活且可维护的Java...

    spring-dm-osgi整合jar包

    它允许开发者利用Spring的依赖注入(DI)和面向切面编程(AOP)特性在OSGi环境中编写和管理服务。Spring DM的主要目标是简化OSGi服务的生命周期管理和配置,使得开发者能够像在非OSGi环境中一样轻松地使用Spring。 ...

Global site tag (gtag.js) - Google Analytics