Author: Michael Krauße
Date: 01.04.2012
EMail: ClickToWriteMail
The Spring-framework is fantastic if you need dependency injection in your application. Since I love OSGI’s idea that a framework provide extension-points which can be extended by other plugins I wanted something similar for my current project. What I need is a very lightweight approach similar to OSGI, which allows me that each plugin can have all configuration already “on board” and can contribute to a framework. Researching and asking at Stackoverflow gave me a link to Spring Dynamic Modules Unfortunatly this approach was a little bit to heavyweight for me since my application does not live in an application-server which supports OSGI.
This article contains my solution for the given problem. Available source-code is distributed under a BSD-License and unclear acronyms have been explained at the end.
At the moment I am working at a client who develops multiple plugins which were build upon a self-written-framework and share an Oracle database during runtime. Two years ago all plugins and the framework have been stored in the same repository-structure. This allowed us to configure the product in Spring configuration-files which belonged to the framework. During time the number of plugins raised and developers were not able to keep plugins up-to-date to latest framework version. Now we run into the problem that all plugin-registration-configuration is done in the framework but we do not want all plugins to be part of the product we deploy. (Plugins which have not been tested against latest version of framework will be deployed on an other server with a framework version which has been tested)
For solving the problem I looked for an approach which adds some OSGI to a Spring application. All I needed was a solution which simple creates s static configuration which is not changeable during runtime and is flexible enough to allow new plugins to register without touching the framework. The Spring Dynamic Modules looked promising but were a little bit heavyweight and I don’t like aspect-oriented-programming anyway if I can avoid it.
Or to make a long story short the only thing I wanted to change was that each plugin registers on its own to the framework. The framework should not know anything about the plugins which run on top of it.
My solution was inspired by OSGI. Removing dynamic plugin (un)loading, and all other OSGI I never knew it exists stuff helped me finding a solution. In my approach I changed the configuration is done in Spring. Instead of a Spring configuration which contains all plugin-registration in the framework the framework creates a pluginRegistry with scope singleton. Each contributing plugin is now able to contribute to this registry. In only has to create pluginFactory which creates instances of the plugin. The instances of the plugin are created with help of the spring-application-context.
Since all pluging-factories are configured as spring singletons they will created during application-startup-time.
You will find more information in the following class-diagram and the source-code if you download it (see above how to do it).
minimalOsgiWithSpring (aka framework) contains all needed classes, where plugin implementations can contribute too
Application – contains a main method, does the work by calling responsible pluginPluginRegistry – plugins register here and returns the plugin which is responsible for handling a specific taskPluginFactory – is able to create new instance of plugins. Each plugin implementation needs to register its plugin in is own instance of that factoryIPlugin – every plugin has to implement this interface. In an OSGI world this would be the extension-pointcore.xml which makes the registry available under the name coreRegistry and an languageApplication which uses this registry<?xml version="1.0" encoding="UTF-8"?>
<!-- author: Michael Krausse -->
<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-2.0.xsd">
<!-- Bean coreRegistry becomes available in spring context. Plugins needs to register against this registry. -->
<bean id="coreRegistry"
class="de.m_krausse.articles.minimalOsgiWithSpring.PluginRegistry">
</bean>
<!-- Application uses coreRegistry. No plugins are configured here this
is done in plugin implementation -->
<bean id="languageApplication"
class="de.m_krausse.articles.minimalOsgiWithSpring.Application">
<property name="pluginRegistry" ref="coreRegistry" />
</bean>
</beans>
pluginOne – is an example for an implementation which contributes to framework
PluginOne – an example implementation of the IPlugin InterfacepluginOne.xml which creates a pluginGermanFactory this class gets a reference to coreRegistry and therefore does the trick<?xml version="1.0" encoding="UTF-8"?>
<!-- author: Michael Krausse -->
<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-2.0.xsd">
<!-- Configures the plugin which does the work of saying hello in German. -->
<bean id="pluginGerman" class="de.m_krausse.articles.minimalOsgiPluginOne.PluginOne">
</bean>
<!-- The factory creates new instances of pluginGerman if coreRegistry
needs a plugin which can say hello in GERMAN. -->
<bean id="pluginGermanFactory"
class="de.m_krausse.articles.minimalOsgiWithSpring.PluginFactory">
<constructor-arg ref="coreRegistry" />
<constructor-arg value="GERMAN" />
<constructor-arg value="pluginGerman" />
</bean>
</beans>
application – describes applicationapplication is the productWith the approach described above it is possible to give your spring application a more OSGI like feeling. Although the approach allows only static configuration (no dynamic (un)loading of plugins) it might work well for situations when static configuration is sufficient.
I made good experience with this approach in a non-clustered tomcat environment. It is integrated into a batch-processing framework used in the output-management.
I am interested in your point of view. If you want drop me a line ClickToWriteMail
Please feel free to download the sources from my example project. You need at least maven 2.X to compile and run the project. Disclaimer You use the source-code on your own risk.
You find the source code under the following URI.
osgiWithSpring.zip
Some descriptions have been borrowed from wikipedia. ;-)
| Acronym | Meaning |
|---|---|
| OSGI | Open Services Gateway initiative framework – is a module system and service platform for the Java programming language that implements a complete and dynamic component model |
| Product | As used in an OSGI world. Consits of different applications and is shipable on its own (if runtime requirements are met) |