应用spring OSGI管理bean
来源:互联网 发布:数据精度 英文 编辑:程序博客网 时间:2024/06/07 10:12
为尊重原创作者,标明原始url如下:
http://bill-xing.iteye.com/blog/1175993
http://www.ralfebert.de/blog/eclipsercp/spring_osgi/
在完成实验工程的过程中,遇到了一些问题,进行了整理,是为文章系列二。
Spring is not only a helpful framework for the server side, its “Spring Dynamic Modules for OSGi” can be beneficial for Eclipse RCP applications on the client side as well:
- Spring’s IoC container is the most well known implementation of dependency injection. As inversion of control and dependency injection are very general concepts for structuring software applications, you may want to use it to inject the dependencies of your UI and non-UI client-side components as well.
- Spring provides a bunch of general-purpose abstractions for other frameworks which are enriched with additional functionality. Some of these might make sense in RCP applications as well. For example, you could use Spring Remoting to communicate with your back-end components.
Getting started
I assume that you know Eclipse RCP and Spring quite well and just want to know how to integrate both.
At first, you need to get the Spring Dynamic Modules plug-ins and add them to your target platform. I recommend keeping those separate in a folder and add a new directory entry to your target definition. You can download all the bundles from theSpring Bundle Repository. I added them to my example target platform as well, so you can look up a list of all required plug-ins or download them as one package:eclipse_rcp_de/spring_osgi.
You should also install the Spring IDE
plug-ins in your Eclipse IDE. These help a lot with editing Spring configuration files. The update site is here:
http://dist.springframework.org/release/IDE
Adding Spring application contexts to your bundles
With Spring Dynamic Modules, every bundle gets its own application context. The XML configuration files are added to the folderMETA-INF/spring/
of your bundle. The naming convention for these files is[module]-context.xml
:
de.ralfebert.someplugin|-- META-INF| |-- MANIFEST.MF| `-- spring| `-- services-context.xml|-- build.properties`-- src
If you’ve installed the Spring IDE, you can add the Spring nature to your plug-in (Plug-in project context menu > Spring Tools > Add Spring Project Nature). You can then create the configuration files usingNew > Spring > Spring Bean Configuration File
.
You can read more about the bundle structure in the Spring documentation: Bundle Format And Manifest Headers
Extender
Spring Dynamic Modules comes with a bundle org.springframework.osgi.extender
that is responsible for instantiating the Spring application contexts. You need to make sure that this bundle is started, because only then the application contexts for your bundles will be available.
When you run your application from the Eclipse IDE, you can configure start levels in thePlug-ins
tab of the run configuration:
For the exported product, you can specify start levels in the Configuration
tab of the product. These settings are written to the fileconfig.ini
in your application configuration folder. Unfortunately, when you add a start level here, the default start levels are not applied any more (see bug#272768). So you need to configure the start levels of the framework bundles as well. This is the correct configuration for the start levels:
An alternative to the config.ini
file is to start the extender programmatically. This can be done by adding the following code in a place that is guaranteed to be used as part of the application startup (for example theActivator
of the bundle that contains the RCP application or the Application
class itself):
// Enforcing that Spring Dynamic Modules extender is startedPlatform.getBundle("org.springframework.osgi.extender").start();
If you updated your run configuration and run your application, you should see the Spring extender startup in the console log:
30.07.2009 19:26:28 org.springframework.osgi.extender.internal.activator.ContextLoaderListener startINFO: Starting [org.springframework.osgi.extender] bundle v.[1.2.0]30.07.2009 19:26:28 org.springframework.osgi.extender.internal.support.ExtenderConfiguration <init>INFO: No custom extender configuration detected; using defaults...
You can read more about the extender in the Spring documentation: The Spring Dynamic Modules Extender bundle
Injecting into view components
At this point, you can use Spring Dynamic Modules to declare beans and inject their dependencies in the same way as on the server-side. But how can you inject dependencies in your view components likeView-
orEditorParts
? To inject their dependencies we need them to be Spring beans. Unfortunately, the Eclipse workbench is responsible for instantiating these objects. How can we delegate this responsibility to the Spring IoC container?
A little detail about the Eclipse extension mechanism comes in handy here. Wherever you can specify a class as attribute of an extension element, you can also specify a factory class (that implementsIExecutableExtensionFactory
). Then Eclipse will not instantiate the object itself but ask the factory instead.
Martin Lippert wrote a SpringExtensionFactory
that will ask the bundle application context for the object. You can read download it below.
After you added the org.eclipse.springframework.util
plug-in to your project and imported the packageorg.eclipse.springframework.util
in your bundle manifest, you can use theSpringExtensionFactory
like this:
<extension point="org.eclipse.ui.views"> <view id="de.ralfebert.someview" class="org.eclipse.springframework.util.SpringExtensionFactory" name="SomeView" restorable="true"> </view></extension>
The SpringExtensionFactory
will look up the bean with the id de.ralfebert.someview
and Eclipse will use this object. You can also specify the bean id independently from the id attribute of the contribution element using:
org.eclipse.springframework.util.SpringExtensionFactory:somebeanid
The bean has to be declared in the contributing plug-in. As view components are usually not singletons, you should use Spring’sprototype
scope (this will make Spring instantiate a new instance every time this bean is requested):
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="de.ralfebert.someview" class="de.ralfebert.SomeViewPart" scope="prototype"/> </beans>
OSGi services
So far we have seen how to declare application contexts for bundles and how to inject dependencies in view components. Every bundle has its own, separate application context - what if multiple bundles want to act together? This is done using OSGi services.
You can export OSGi services in one bundle and import them in another bundle using a special XML namespace for OSGi:
Exporting a service
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:osgi="http://www.springframework.org/schema/osgi" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd"> <bean id="someService" class="de.ralfebert.services.internal.SomeServiceImpl"/> <osgi:service ref="someService" interface="de.ralfebert.services.ISomeService"/></beans>
Importing a service
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:osgi="http://www.springframework.org/schema/osgi" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd"> <osgi:reference id="someService" interface="de.ralfebert.services.ISomeService"/></beans>
You can read more about importing and exporting services in the Spring documentation:Exporting A Spring Bean As An OSGi Service,Defining References To OSGi Services
- 应用spring OSGI管理bean
- 在Eclipse RCP中应用Spring OSGI 管理bean(一)
- 在Eclipse RCP中应用Spring OSGI 管理bean(二)
- Spring Bean基本管理
- Spring 管理Bean
- spring管理bean原理
- spring管理bean生命周期
- spring的bean管理
- Spring Bean基本管理
- spring bean 管理
- Spring-管理bean
- 使用Spring管理Bean
- Spring bean 生命周期管理
- spring管理bean生命周期
- spring Bean管理
- Spring的bean管理
- Spring Bean 生命周期管理
- spring的bean管理
- 最大子序列和问题
- Linux运维日常监控的对象
- Android对文件的保存操作
- android 使用Scroller实现缓慢移动
- Debian 安装Flash插件
- 应用spring OSGI管理bean
- 【博弈&动态规划】poj2068Nim
- d-dimensional Delaunay
- gdb调试
- Java @Override报错解决办法
- 样在VS中设置编译选项(以启用OpenMP)
- 确保对象的唯一性——单例模式 (一)
- n-sphere
- linux程序设计笔记--pthread--semaphore