SpringDM笔记9-SpringDM Stand Extender 运行机制

    扩展模型指一个Bundle在扫描其他Bundle内容的过程中,该Bundle代表被扫描Bundle执行其Action. 而在SpringDM中,扩展模型指当在MANIFEST.MF文件或Bundle的内容中有指定的扩展存在时,SpringDM应该自动

的触发连锁的事件(Event),即创建Spring Context, 该Context包括一个特指的类型上下文:OsgiBundle-

XmlApplicationContext.

    任何部署到OSGi环境中的Bundle,SpringDM将检查该Bundle的SpringDM触发点,如果找到该出发点,该

Bundle将被赋予一个OsgiBundleXmlApplicationContext 类型的上下文;如果没找到触发点,SpringDM日志

将输出日志:

    No Application context created for bundle<bundle_name>

但是扫描仍将继续。

    SpringDM中有两中类型的Extender: Stand Extender和Web Extend,用于创建Context的默认Trigger如下:

   Stand Extender:

   /METa-INF/spring/*.xml: 放置与搞目录下的xml配置文件将用于SpringContext的创建;

   Spring-Context mainfest value:这是一种更细粒度度的控制SpringContext的创建;

   Web Extender:

   .war bundle extension: 以.war作为扩展名表明该Bundle将被部署一个Web应用。

 

   The stand extender primarily listens for bundle starting events, but it also looks for Spring-powered bundles that are already in the active state when it is itself started.

   The default extender behavior is to retrieve the Spring configuration files from the bundle space, as it’s defined in the OSGi specification.

1. 标准的SpringOSGi组件的结构

1.1 DEFAULT BEHAVIOR FOR LOCATING SPRING CONFIGURATION FILES

      my-springpowered-bundle.jar
        META-INF/
           MANIFEST.MF
           spring/
              application-context-1.xml
              application-context-2.xml
        com/
              manning/
                    sdmia/
                       ...

1.2 DEFINING THE LOCATION OF SPRING CONFIGURATION FILES WITH THE SPRING-CONTEXT

     HEADER

     Spring-Context: config/app-context-1.xml, config/app-context-2.xml

     Spring-Context: config/*.xml

     Spring-Context: config/**/*.xml

     如果一个Bundle中同时有上述两种配置方式存在,则第二种优于第一种;如果一个Bundle 有Fragement,则

     Fragement中的配置优于Host Bundle中得配置。

1.3 SPRING DM’S RESOURCE LOCATION BEHAVIOR

     Spring Resource Abstraction

     The Spring Framework defines an abstraction to load resources from an application context. This

     abstraction is based on the Resource interface, which represents the access to a resource and is

     agnostic to the underlying resource medium (filesystem, classpath, URL, and so on). Spring   

     defines the ResourceLoader interface, which is meant to be implemented by objects that can load

     resources (a Spring application context always implements this interface).

     Spring supports several prefixes: classpath, file, http.

     Spring DM introduces a new Resource implementation, OsgiBundleResource , which encapsulates

     all the necessary logic for proper resource loading from a bundle in an OSGi environment.

     OSGi resource search strategies with Spring DM:

     (1)OSGi search strategy:Class space

     Prefixes:classpath:,classpath*:

     Description:Search is delegated to the bundle classloader. The bundle itself, imported packages,

     and required bundles are then scanned using the same semantics as the Bundle.getResource

     method.

     (2)OSGi search strategy:JAR file

     Prefixes:osgibundlejar:

     Description:Only the bundle itself is scanned, using the same semantics as the Bundle.getEntry

     method.

     (3)OSGi search strategy:Bundle space

     Prefixes:osgibundle:

     Description:The bundle and its fragments (if any) are scanned. Delegates internally to the   

     Bundle.findEntries method. This is Spring DM’s default resource-loading strategy.

     配置示例:

     Spring-Context: config/application-context.xml
     Spring-Context: osgibundle:config/application-context.xml

     这两种配置在OSGi环境中是等价的。

     <bean id="someBean" class="com.manning.sdmia.SomeBean">
        <property name="resource" value="classpath:help/section1.html" />
     </bean>

1.4 ORGANIZING SPRING CONFIGURATION FILES IN A BUNDLE

     A typical Spring-powered bundle of this sort would have the following structure:

     my-springpowered-bundle.jar
          META-INF/
             MANIFEST.MF
             spring/
                modulename-context.xml
                modulename-osgi-context.xml
          com/
                manning/
                      sdmia/
                           ...

2. Bundle中初始化和销毁Spring容器

    When the Spring DM extender is started, it scans the OSGi container for bundles in the active

    state and bootstraps the application contexts for those it identifies as Spring-powered.

    The Spring DM extender creates application contexts asynchronously; application contexts are

    started in a different thread than the one that started the bundle (usually a thread owned by the

    OSGi platform).

    SpringDM在不同的线程中创建上下文主要有以下两个原因:

    (1)OSGi规范推荐Event尽力在短时间 内进行,而创建应用上下文是需要时间的,如果创建应用上下文发生在OSGi

    Event线程中,它将会阻止平台中其他任务的运行从而减缓了容器的启动;

    (2)创建一个应用上下文时,The Extend Bundle需要应用上下文中Service的依赖被满足;如果创建上下文这个

    任务是同步执行的,那么Bundle启动的顺序就需要很仔细的管理,要避免Service之间循环依赖现象发生。

 

    The Spring DM extender is a bundle listener!

    In Spring DM 1.2, the extender is a synchronous bundle listener, registered by the activator of the

    Spring DM extender bundle. What exactly is a synchronous bundle listener? It’s an  

    implementation of the observer pattern , which allows code to react to bundle events, such as

    activation, startup, or stopping. There are two kinds of bundle listeners, synchronous and

    asynchronous (represented by two interfaces, SynchronousBundleListener and BundleListener

    respectively), and the way the OSGi platform notifies them is slightly different.

 

    Synchronous listeners receive more events than their asynchronous brethren (兄弟), as they’re  

    notified of starting and stopping events (the targeted bundle is on the way to being started or

    stopped, respectively). Second, they’re called during the processing of the event . In the case of

    bundle startup, the caller asks the platform to start the bundle, the platform notifies the    

    synchronous listeners, each does its work, and the bundle is started (and then the platform

    broadcasts a started event, but that’s another story). With the synchronous method, listeners are

    always notified during the processing of the event.

 

    Asynchronous bundle listener notification isn’t as straightforward as the synchronous case. The

    OSGi platform doesn’t place any constraints on the timeliness of notification and can add events

    to a queue and let a background thread dispatch them to the asynchronous listeners. There is no

    guarantee that event ordering is respected (the started event of the bundle could be delivered

    after the corresponding stopped event). This doesn’t make asynchronous listeners useless, but

    the dispatch mechanism needs to be understood when writing listeners of this type!

 

    The BundleListener and SynchronousBundleListener interfaces define the same method, the

    synchronous flavor being simply a marker-based extension of the asynchronous interface.

    Synchronous bundle listeners must be used with caution, because they can slow the whole

    platform if their processing takes too much time. The Spring DM extender is a synchronous

    bundle listener but it delegates the creation of Spring application contexts to different threads by

    default.

3. HOW SPRING DM DESTROYS APPLICATION CONTEXTS

    The Spring DM extender takes care of the destruction of application contexts (on stopping bundle

    events ) and accomplishes this crucial operation in a managed and safe way.

    Through application context destruction, Spring DM accomplishes the following things:
    ■ Calls the shutdown method on Spring beans
    ■ Unregisters exported services
    ■ Informs the OSGi container that imported services are no longer used

    The destruction is handled synchronously : the OSGi container is told to stop a Spring-powered

    bundle, it sends a stopping event, the Spring DM extender receives the event and stops the

    bundle application context (in the same thread ), and then control returns to the container, which

    then stops the bundle.

    The destruction is done synchronously because the application context must be destroyed before

    the bundle is stopped. Once stopped, a bundle—and in particular, its bundle context—can’t be

    used anymore.

4. STOPPING THE EXTENDER

    Stopping the extender consists of destroying the application contexts in the right order . Why must

    there be a “right” order? Well, application contexts can have dependencies on each other; some

    can export services that others consume. The right order is therefore based on the way bundles

    are connected through the service registry. Spring DM must compute the dependency graph of

    Spring-powered bundles by analyzing their service relationships.

    解决依赖关系的SpringDM的算法:

    Spring DM would first track bundles that either don’t export any services, or export services that

    aren’t referenced (used). These bundles are destroyed immediately (although Spring DM will   

    additionally attempt to do this in the reverse order of their creation) and whatever services

    they’re using are released. The services these bundles were using might then no longer be

    referenced, and Spring DM would find their owning bundles and destroy their application contexts.

    This cycle continues until there are no more application contexts left to shut down.

    解决循环依赖关系:

    In this case, Spring DM has no choice other than to break the cycle by trying to find the most   

    appropriate bundle to stop first. Spring DM bases its choice on an OSGi property of services: the

    service ranking . Services are looked up from the service registry by their interface. In the case

    that there are several services implementing the same interface, the one with the highest service

    ranking is returned by the OSGi platform. For each remaining bundle, Spring DM finds the highest

    service ranking number and destroys the application context whose bundle has the lowest service

    ranking among the set just calculated. If there is a tie in lowest ranking, Spring DM uses the

    bundle ID (an indicator of start order) as a tiebreaker, stopping the bundle with the highest ID 

    (which was thus started last). This will hopefully break the cycle, and Spring DM can restart its   

    algorithm at the beginning to find other application contexts to destroy.

5. Customizing application context creation

    Directives for the Spring-Context header:

    配置文件默认值:

    Bundle-Context:*;

    Spring-Context:*;

    配置文件默认路径:

    /META-INF/spring,如果指定了其他配置文件路径,默认路径将被忽略。

    (1)Directive:create-asynchronously

    Possible values:true, false

    Description:Tells the extender to create the bundle application context asynchronously or  

    synchronously. Default is true (asynchronously).

    (2)Directive:wait-for-dependencies

    Possible values:true, false

    Description:Controls whether application context creation should wait for all mandatory imported

    services to be available. Default is true.

    (3)Directive:timeout

    Possible values:integer

    Description:Indicates the time (in seconds) to wait for mandatory imported services to become

    available before failing the creation of the application context. Default is 300 seconds (5 minutes).

    (4)Directive:publish-context

    Possible values:true, false

    Description:Controls whether the bundle application context is published in the OSGi service

    registry. Default is true.

5.1 CREATE-ASYNCHRONOUSLY

    By setting the create-asynchronously directive to false, the creation of the application context

    occurs in a thread managed by the OSGi platform,how to set the create-asynchronously  

    directive:

    (1) 用默认的配置路径异步创建上下文(默认值):

    Spring-Context: *;create-asynchronously:=true

    (2) 指定配置文件路径同步创建上下文:

    Spring-Context: config/application-context.xml;create-asynchronously:=false

5.2 WAIT-FOR-DEPENDENCIES

    默认值:Spring-Context: *;wait-for-dependencies:=true

    Spring-Context: config/application-context.xml;wait-for-dependencies:=false

    With this setting, mandatory dependencies are treated as optional, and Spring beans using them

    will be injected with a service proxy that isn’t currently backed by an actual service retrieved

    from the service registry.

    推荐异步创建,同步情况下有可能导致依赖死锁。

5.3 TIMEOUT

    默认值:Spring-Context:*;timeout:=300

    Spring-Context: config/application-context.xml;timeout:=120

    With this setting, an application context will wait for its mandatory dependencies for 300 seconds

    before the creation attempt fails. The timeout directive makes sense only when application

    contexts wait for their mandatory dependencies, so it’s ignored when the wait-for-dependencies

    directive is set to false。

5.4 PUBLISH-CONTEXT

    默认值:Spring-Context:*;publish-context:=true

    Spring-Context: config/application-context.xml;publish-context:=false

    指从Bundle配置文件路径中创建上下文,但是不将该上下文作为一个服务注册至OSGi 注册中心。

你可能感兴趣的:(spring)