1. THE SPRING DM EVENT MECHANISM
The available events are Java classes in the org.springframework.osgi.context.event package and
they’re listed below:
(1)OsgiBundleContextRefreshedEvent : Published when an application context is successfully started
or refreshed.
(2)OsgiBundleContextFailedEvent : Published when the creation of an application context fails.
(3)OsgiBundleContextClosedEvent : Published when an application context is closed, usually when
a Spring-powered bundle is stopped.
2. Spring Container Event与SpringDM Event的区别
(1)相同点:Spring DM’s OsgiBundleContextRefreshedEvent is raised when the refresh method of the
ConfigurableApplicationContext interface is called, which is the same point in the lifecycle that the
Spring ContextRefreshedEvent is raised.
(2)不同点:Spring’s standard event system propagates container events to interested beans in the
same application context , whereas Spring DM propagates events outside the containing
application context,possibly betwwen bundles .
(3)Spring’s standard event mechanism:
The Spring lightweight container comes with a built-in event mechanism that allows beans to be
notified of lifecycle steps in their parent application context. Beans interested in receiving events
need to implement the ApplicationListener interface, and the application context will register
them as listeners when it creates them. They will be notified of events such as the application
context starting, stopping, or closing. Spring also allows beans to raise their own events, which
will be propagated the same way as built-in ones. This makes it easy to use an event-driven
approach in Spring applications, which would normally be enough for simple use cases.
3. 注册SpringDM Event监听器
By declaring a bean that implements the OsgiBundleApplicationContextListener interface and then
publishing it as an OSGi service. Spring DM will automatically detect it and add it to the list of
managed listeners. The listener interface declares only one method, onOsgiApplicationEvent, with
the event as the only parameter.
An OSGi bundle application listener:
package com.manning.sdmia.ch04;
import org.springframework.osgi.context.event.OsgiBundleApplicationContextEvent;
import org.springframework.osgi.context.event.OsgiBundleApplicationContextListener;
import org.springframework.osgi.context.event.OsgiBundleContextClosedEvent;
import org.springframework.osgi.context.event.OsgiBundleContextRefreshedEvent;
public class ApplicationContextObserver implements
OsgiBundleApplicationContextListener<OsgiBundleApplicationContextEvent> {
private transient int countRefreshed = 0;
private transient int countClosed = 0;
public void onOsgiApplicationEvent(OsgiBundleApplicationContextEvent evt) {
if(evt instanceof OsgiBundleContextRefreshedEvent) {
countRefreshed++;
} else if(evt instanceof OsgiBundleContextClosedEvent) {
countClosed++;
}
}
public int getCountRefreshed() {
return countRefreshed;
}
public int getCountClosed() {
return countClosed;
}
}
Declaring and exporting a listener:
<?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="observer" class="com.manning.sdmia.ch04.ApplicationContextObserver" />
<osgi:service ref="observer" interface="org.springframework.osgi.context.event.
OsgiBundleApplicationContextListener"/>
</beans>
4. THE WHITEBOARD PATTERN
The whiteboard pattern is more about “event-based” communication, so that’s why we don’t use
the exact same vocabulary as with the observer pattern: observables become event producers,
and observers become listeners or consumers.
In an OSGi environment, event-based communication between components can be implemented
by following the observer pattern , but the dynamic nature of OSGi becomes a real hindrance to
its use. The difficulty mainly consists in maintaining consistent linkages between producers and
consumers, because to provide modular interbundle connections, they should be OSGi services,
and as such, they can disappear or reappear at any moment. A producer would have to maintain
its own collection of listeners, usually with the use of a ServiceTracker . Even if this solution could
work well, it would be cumbersome and error prone.
Another solution might consist of using some kind of middle tier to decouple producers and
listeners. Listeners would register with this middle tier, and producers could retrieve listeners from
it in a totally safe manner. The intricacies we described previously would now be handled by this
middle tier. Luckily for us, this middleware already exists in OSGi, in the shape of the service
registry!
In the whiteboard pattern, each time a producer wants to send an event to its listeners, it
retrieves it from the whiteboard and proceeds with the event dispatch. The collection of listeners
it receives from the registry can be seen as a snapshot of the listeners that are registered at the
moment the event is dispatched. The producer relies on the service registry to correctly maintain
the collection of listeners. The usual way to retrieve listeners is to track them through their
interface with a ServiceTracker and use the getServices method.