登錄 OSGi 服務

您可以建立一個物件,將它登錄為可供協力廠商特性使用的 OSGi 服務。

關於這項作業

通過使用一般舊 Java 程式碼,您可以建立一個物件,然後利用 BundleContext 類別將它登錄為一項服務。 由於必須執行程式碼,您通常是在 BundleActivator 介面中登錄這個物件。 當您登錄物件時,您可以指定它所提供的介面,並供應一項內容對映。 這會傳回 ServiceRegistration 物件;必要的話,您隨時可以利用 ServiceRegistration 物件來變更內容。 服務完成之後,您再利用 ServiceRegistration 物件,將服務取消登錄。

如果要取得服務,您將查詢 BundleContext 來尋找實作必要介面的服務,以及選擇性地供應 LDAP 語法的過濾器來比對服務內容。 依您呼叫的方法而定,您可以擷取最佳相符項或所有相符項。 之後,您可以使用傳回的 ServiceReference,它會提供在您的程式碼中做進一步比對的內容。 您可以利用 ServiceReference 來取得實際的服務物件。 用完服務之後,您再利用 BundleContext 來釋出服務。

程序

  1. 在您的軟體組中,新增下列程式碼來宣告服務介面。
    package com.ibm.foo.simple;
    
    /**
     * 我們的多功能範例介面
     */
    public interface Foo
    {
    }
  2. 指定介面的實作程式碼。
    package com.ibm.foo.simple;
    
    /**
     * The implementation of the Foo interface
     */
    public class FooImpl implements Foo
    {
        public FooImpl()
        {
        }
        public FooImpl(String vendor)
        {
        }
    
        /**
         * used by the ServiceFactory implementation.
         */
        public void destroy() {
    
        }
    }
  3. 利用 BundleContext 來登錄服務、修改服務內容,以及直接在程式碼中將服務取消登錄。
    import java.util.Dictionary;
    
    import org.osgi.framework.BundleContext;
    import org.osgi.framework.ServiceRegistration;
    
    /**
     * Registers and unregsiters a Foo service directly,
     * and shows how to modify the service properties in code.
     */
    public class FooController
    {
    
        private final BundleContext bundleContext;
        private ServiceRegistration<Foo> sr;
    
        public FooController( BundleContext bundleContext )
        {
            this.bundleContext = bundleContext;
        }
    
        public void register(Dictionary<String, Object> serviceProperties) {
            Foo foo = new FooImpl();
            //typed service registration with one interface
            sr = bundleContext.registerService( Foo.class, foo, serviceProperties );
            //or
            //untyped service registration with one interface
            sr = (ServiceRegistration<Foo>)bundleContext.registerService( 
                   Foo.class.getName(), foo, serviceProperties );
            //or
            //untyped service registration with more than one interface (or class)
            sr = (ServiceRegistration<Foo>)bundleContext.registerService(new String[] {
                   Foo.class.getName(), FooImpl.class.getName()}, foo, serviceProperties );
        }
    
        public void modifyFoo(Dictionary<String, Object> serviceProperties) {
            //with the service registration you can modify the service properties at any time
            sr.setProperties( serviceProperties );
        }
    
        public void unregisterFoo() {
            //when you are done unregister the service using the service registration
            sr.unregister();
        }
    
    }
  4. 從另一個類別取得及傳回服務:
    package com.ibm.foo.simple;
    
    import java.util.Collection;
    
    import org.osgi.framework.BundleContext;
    import org.osgi.framework.InvalidSyntaxException;
    import org.osgi.framework.ServiceReference;
    
    /**
     * A simple Foo client that directly obtains the Foo service and returns it when done.
     */
    public class FooUser
    {
    
        private final BundleContext bundleContext;
    
        public FooUser( BundleContext bundleContext )
        {
            this.bundleContext = bundleContext;
        }
    
        /**
         * assume there's only one Foo
         */
        public void useFooSimple() {
            ServiceReference<Foo> sr = bundleContext.getServiceReference( Foo.class );
            String[] propertyKeys = sr.getPropertyKeys();
            for (String key: propertyKeys) {
                Object prop = sr.getProperty( key );
                //think about whether this is the Foo we want....
            }
            Foo foo = bundleContext.getService( sr );
            try {
                //use foo
            } finally {
                //we're done
                bundleContext.ungetService( sr );
            }
        }
    
        /**
         * Use a filter to select a particular Foo. Note we get a collection back and have to pick one.
         * @throws InvalidSyntaxException
         */
        public void useFooFilter() throws InvalidSyntaxException {
            Collection<ServiceReference<Foo>> srs = bundleContext.getServiceReferences( 
              Foo.class, "(&(service.vendor=IBM)(id='myFoo')" );
            ServiceReference<Foo> sr = srs.iterator().next();
            String[] propertyKeys = sr.getPropertyKeys();
            for (String key: propertyKeys) {
                Object prop = sr.getProperty( key );
                //think about whether this is the Foo we want....
            }
            Foo foo = bundleContext.getService( sr );
            try {
                //use foo
            } finally {
                //we're done
                bundleContext.ungetService( sr );
            }
        }
    }

指示主題類型的圖示 作業主題

檔名:twlp_feat_service_pojo.html