登錄 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;
    
    /**
     * Foo 介面的實作
     */
    public class FooImpl implements Foo
    {
        public FooImpl()
        {
        }
        public FooImpl(String vendor)
        {
        }
    
        /**
         * 供 ServiceFactory 實作使用。
         */
        public void destroy() {
    
        }
    }
  3. 利用 BundleContext 來登錄服務、修改服務內容,以及直接在程式碼中將服務取消登錄。
    import java.util.Dictionary;
    
    import org.osgi.framework.BundleContext;
    import org.osgi.framework.ServiceRegistration;
    
    /**
     * 直接登錄及取消登錄 Foo 服務, * 並顯示如何修改程式碼中的服務內容。
     */
    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();
            //單一介面的類型化服務登錄
            sr = bundleContext.registerService( Foo.class, foo, serviceProperties );
            //或
            //有單一介面的非類型化服務登錄
            sr = (ServiceRegistration<Foo>)bundleContext.registerService(
                   Foo.class.getName(), foo, serviceProperties );
            //或
            //有多重介面(或類別)的非類型化服務登錄
            sr = (ServiceRegistration<Foo>)bundleContext.registerService(new String[] {
                   Foo.class.getName(), FooImpl.class.getName()}, foo, serviceProperties );
        }
    
        public void modifyFoo(Dictionary<String, Object> serviceProperties) {
            //透過服務登錄,您隨時可以修改服務內容
            sr.setProperties( serviceProperties );
        }
    
        public void unregisterFoo() {
            //完成之後,利用服務登錄,將服務取消登錄
            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;
    
    /**
     * 簡式 Foo 用戶端,直接取得 Foo 服務,完成之時,將它傳回。
     */
    public class FooUser
    {
    
        private final BundleContext bundleContext;
    
        public FooUser( BundleContext bundleContext )
        {
            this.bundleContext = bundleContext;
        }
    
        /**
         * 假設只有一個 Foo
         */
        public void useFooSimple() {
            ServiceReference<Foo> sr = bundleContext.getServiceReference( Foo.class );
            String[] propertyKeys = sr.getPropertyKeys();
            for (String key: propertyKeys) {
                Object prop = sr.getProperty( key );
                //思考一下,這是不是我們想要的 Foo...
            }
            Foo foo = bundleContext.getService( sr );
            try {
                //使用 foo
            } finally {
                //我們完成了
                bundleContext.ungetService( sr );
            }
        }
    
        /**
         * 利用過濾器來選取特定 Foo。請注意,我們會取回一個集合,必須挑選一個。
         * @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 );
                //思考一下,這是不是我們想要的 Foo...
            }
            Foo foo = bundleContext.getService( sr );
            try {
                //使用 foo
            } finally {
                //我們完成了
                bundleContext.ungetService( sr );
            }
        }
    }

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



「時間戳記」圖示 前次更新: 2016 年 11 月 30 日
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-libcore-mp&topic=twlp_feat_service_pojo
檔名:twlp_feat_service_pojo.html