SpringDM笔记10-Listening to extender events with the whiteboard pattern

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.

 

 

你可能感兴趣的:(Pattern)