<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Chasing an mobile web vision

    闖蕩在移動(dòng)互聯(lián)網(wǎng)的世界中

    OSGi介紹(六)OSGi的service

    在給出采用service方式實(shí)現(xiàn)的“扶貧助手”之前,我們稍微回顧一下上一篇的成果。
    在(五)中,我們看到程序被分成多個(gè)bundle后,程序的模塊程度得到提高,而控制模塊間的耦合度由Import-Package和Export-Package來(lái)控制,相對(duì)比較靈活。另一方面程序的更新和升級(jí)的粒度變小了。誰(shuí)都知道只更新部分要比全部更新強(qiáng),尤其當(dāng)更新發(fā)生在一些需要建立昂貴的連接時(shí),細(xì)粒度會(huì)節(jié)省不少花銷(xiāo)。除了這些,我們看不到其他新鮮的東西。說(shuō)白了,也就是挖空心思想一些design pattern來(lái)劃分程序模塊。
     
    好了,馬上就新鮮了。下面你會(huì)看到通過(guò)采用service方式來(lái)改造(五)中的程序,gui bundle在某些情況下不用重新啟動(dòng),就能直接某些適應(yīng)需求的變更!
    先給出model bundle的代碼,該bundle包含兩個(gè)java package,分別是:
    com.bajie.test.family.model
    com.bajie.test.family.model.impl
    在com.bajie.test.family.model這個(gè)package中包含如下的class和interface:
    package com.bajie.test.family.model;
    import java.util.List;
    import javax.swing.table.AbstractTableModel;
    public abstract class FamilyInfoDatabase extends AbstractTableModel{
       
        public abstract void sort(SortingFamilyInfoCriteria sortField) throws IllegalArgumentException;
       
        public abstract void addEntry(List columns, List values) throws IllegalArgumentException;
        public abstract void deleteEntry(String familyName);
        public abstract void update(String familyName,List columns, List values)throws IllegalArgumentException;
    }

    這是database的model,與(五)定義成interface不同,我們直接讓它繼承了AbstractTableModel,這是因?yàn)槲覀兿M?dāng)數(shù)據(jù)或顯示需求變化時(shí),gui上的JTable能獲得通知,并顯示更新的結(jié)果。SortingFamilyInfoCriteria這個(gè)類型下文會(huì)給出說(shuō)明。
     
    package com.bajie.test.family.model;
    public class FamilyInfoEntry {
        private String familyName;
        private int population;
        private int incomePerYear;
       
        public FamilyInfoEntry(String familyName,int population,int income){
            this.familyName = familyName;
            this.population = population;
            this.incomePerYear = income;
        }
       
        public String getFamilyName() {
            return familyName;
        }
        public int getIncomePerYear() {
            return incomePerYear;
        }
        public int getPopulation() {
            return population;
        }
    }

    這個(gè)類的結(jié)構(gòu)和在(五)中完全一樣,用來(lái)紀(jì)錄一條家庭信息。唯一不同的是,在(五)中我們把它放入了實(shí)現(xiàn)(.impl)package中,在后面給出bundle的manifest文件時(shí),我將解釋為什么要這樣改。
     
    package com.bajie.test.family.model;
    public interface FamilyInfoColumn {
        public Object getColumnValue(FamilyInfoEntry entry);
       
        public String getColumnName();
    }
    這個(gè)類用來(lái)描述table中的某個(gè)列。
    package com.bajie.test.family.model;
    import java.util.Comparator;
    public interface SortingFamilyInfoCriteria extends Comparator{
        public String getSortFieldString();
    }
    這個(gè)類將用于對(duì)家庭紀(jì)錄按某一列的值進(jìn)行排序。
    在com.bajie.test.family.model.impl這個(gè)package中包含上面抽象類和interface的實(shí)現(xiàn):
    package com.bajie.test.family.model.impl;
    import java.util.Arrays;
    import java.util.LinkedList;
    import java.util.List;
    import org.osgi.framework.BundleActivator;
    import org.osgi.framework.BundleContext;
    import org.osgi.framework.Constants;
    import org.osgi.framework.ServiceEvent;
    import org.osgi.framework.ServiceListener;
    import org.osgi.framework.ServiceReference;
    import com.bajie.test.family.model.FamilyInfoColumn;
    import com.bajie.test.family.model.FamilyInfoDatabase;
    import com.bajie.test.family.model.FamilyInfoEntry;
    import com.bajie.test.family.model.SortingFamilyInfoCriteria;
    public class FamilyDatabase extends FamilyInfoDatabase implements  BundleActivator,
            ServiceListener {
        private LinkedList familyEntryList = new LinkedList();
        private Object[] sortedValues = null;
        private LinkedList columns = new LinkedList();
        private BundleContext context;
        public int getColumnCount() {
            return this.columns.size();
        }
        public String getColumnName(int index) {
            return ((FamilyInfoColumn)columns.get(index)).getColumnName();
        }
       
        public Object getValueAt(int row, int column) {
            FamilyInfoEntry entry = (FamilyInfoEntry) this.sortedValues[row];
            if(column >= this.familyEntryList.size()){
                return null;
            }
            return ((FamilyInfoColumn) this.columns.get(column))
                    .getColumnValue(entry);
        }
        public int getRowCount() {
            return this.familyEntryList.size();
        }
        public void addEntry(List columns, List values)
                throws IllegalArgumentException {
        }
        public void deleteEntry(String familyName) {
        }
        public void update(String familyName, List columns, List values)
                throws IllegalArgumentException {
        }
        public void sort(SortingFamilyInfoCriteria sortField) {
            Arrays.sort(this.sortedValues, sortField);
        }
        public void start(BundleContext context) throws Exception {
            this.context = context;
            this.familyEntryList.add(new FamilyInfoEntry("Zhang", 3, 1200));
            this.familyEntryList.add(new FamilyInfoEntry("Li", 6, 1800));
            this.familyEntryList.add(new FamilyInfoEntry("Liu", 5, 1500));
            this.familyEntryList.add(new FamilyInfoEntry("Wang", 4, 1300));
           
            this.sortedValues = this.familyEntryList.toArray();
     //向framework注冊(cè)一個(gè)類型為FamilyInfoDatabase的服務(wù)
            context.registerService(FamilyInfoDatabase.class.getName(),this,null);
     //向framework注冊(cè)三個(gè)服務(wù),每個(gè)服務(wù)的類型既為FamilyInfoColumn,也是SortingFamilyInfoCriteria
            String[] clazzes = new String[] {FamilyInfoColumn.class.getName(),SortingFamilyInfoCriteria.class.getName()};
            context.registerService(clazzes,new FamilyNameColumn(),null);
            context.registerService(clazzes,new FamilyPopulationColumn(),null);
            context.registerService(clazzes,new FamilyIncomeColumn(),null);
           
     //向framework查找所有注冊(cè)類型為FamilyInfoColumn的服務(wù)
     //先獲得服務(wù)的引用
            ServiceReference[] columnRefs = context.getServiceReferences(
                    FamilyInfoColumn.class.getName(), null);
            FamilyInfoColumn column = null;
            for (int i = 0; i < columnRefs.length; i++) {
                System.out.println(i + ":" + ((String[])(columnRefs[i].getProperty(Constants.OBJECTCLASS)))[0]);
         //通過(guò)引用獲得具體的服務(wù)對(duì)象,每一個(gè)對(duì)象都將轉(zhuǎn)化成gui中table的一列
                column = (FamilyInfoColumn) context.getService(columnRefs[i]);
                if (column != null) {
                    this.columns.add(column);
                }else{
                    System.out.println("null service object.");
                }
            }

     //注冊(cè)服務(wù)偵聽(tīng)器,該偵聽(tīng)器專門(mén)偵聽(tīng)FamilyInfoColumn服務(wù)對(duì)象的動(dòng)態(tài)(主要是增加和刪除)
            context.addServiceListener(this,"(" + Constants.OBJECTCLASS + "="
                    + FamilyInfoColumn.class.getName() + ")");
        }
        public void stop(BundleContext context) throws Exception {
        }
        public void serviceChanged(ServiceEvent event) {
            switch (event.getType()) {
            case ServiceEvent.MODIFIED:
                return;
            case ServiceEvent.REGISTERED://表明有新的列產(chǎn)生了。
                ServiceReference ref = event.getServiceReference();
                Object service = this.context.getService(ref);
                this.columns.add(service);
                this.fireTableStructureChanged();//通知gui,表結(jié)構(gòu)發(fā)生變化
                return;
            case ServiceEvent.UNREGISTERING://表明有些列將被刪除
                ref = event.getServiceReference();
                service = this.context.getService(ref);
                this.columns.remove(service);
                this.fireTableStructureChanged();//通知gui,表結(jié)構(gòu)發(fā)生變化
                return;
            }
        }

        //這個(gè)類定義一個(gè)“Family Name”這個(gè)列,以及如何按這個(gè)列的值進(jìn)行排序
        class FamilyNameColumn implements FamilyInfoColumn,SortingFamilyInfoCriteria {
            private static final String COLUMNNAME = "Family Name";
           
            public Object getColumnValue(FamilyInfoEntry entry) {
                return entry.getFamilyName();
            }
           
           
            public String getColumnName() {
                return FamilyNameColumn.COLUMNNAME;
            }
           
            public String getSortFieldString() {
                return FamilyNameColumn.COLUMNNAME;
            }
            public int compare(Object obj1, Object obj2) {
                if (obj1 == obj2) {
                    return 0;
                }
                FamilyInfoEntry en1 = (FamilyInfoEntry)obj1;
                FamilyInfoEntry en2 = (FamilyInfoEntry)obj2;
               
                return en1.getFamilyName().compareTo(en2.getFamilyName());
            }
           
        }
        //這個(gè)類定義一個(gè)“Family Population”這個(gè)列,以及如何按這個(gè)列的值進(jìn)行排序
        class FamilyPopulationColumn implements FamilyInfoColumn, SortingFamilyInfoCriteria {
            private static final String COLUMNNAME = "Family Population";
            public Object getColumnValue(FamilyInfoEntry entry) {
                return new Integer(entry.getPopulation());
            }
            public String getColumnName() {
                return FamilyPopulationColumn.COLUMNNAME;
            }
           
            public String getSortFieldString() {
                return FamilyPopulationColumn.COLUMNNAME;
            }
           
            public int compare(Object obj1, Object obj2) {
                if (obj1 == obj2) {
                    return 0;
                }
                FamilyInfoEntry en1 = (FamilyInfoEntry)obj1;
                FamilyInfoEntry en2 = (FamilyInfoEntry)obj2;
               
                return en1.getPopulation() - en2.getPopulation();
            }
        }
       
        //這個(gè)類定義一個(gè)“Family Income”這個(gè)列,以及如何按這個(gè)列的值進(jìn)行排序
        class FamilyIncomeColumn implements FamilyInfoColumn, SortingFamilyInfoCriteria {
            private static final String COLUMNNAME = "Family Income";
            public Object getColumnValue(FamilyInfoEntry entry) {
                return new Integer(entry.getIncomePerYear());
            }
            public String getColumnName() {
                return FamilyIncomeColumn.COLUMNNAME;
            }
           
           
            public String getSortFieldString() {
                return FamilyIncomeColumn.COLUMNNAME;
            }
            public int compare(Object obj1, Object obj2) {
                if (obj1 == obj2) {
                    return 0;
                }
                FamilyInfoEntry en1 = (FamilyInfoEntry)obj1;
                FamilyInfoEntry en2 = (FamilyInfoEntry)obj2;
               
                return en1.getIncomePerYear() - en2.getIncomePerYear();
            }
           
        }
    }
     
    與(五)相比,最大的不同就是表結(jié)構(gòu)的“列”是通過(guò)查找所有類型為FamilyInfoColumn的服務(wù)對(duì)象而組成的。而通過(guò)framework提供的服務(wù)偵聽(tīng)機(jī)制(即實(shí)現(xiàn)ServiceListener接口并注冊(cè)到framework中),bundle能夠獲得該類服務(wù)對(duì)象的動(dòng)態(tài)事件通知,如果該事件是新服務(wù)注冊(cè),則添加一個(gè)顯示列,如果是服務(wù)被注銷(xiāo),則刪除對(duì)應(yīng)的顯示列。
     
    下面是bundle的manifest文件
    Manifest-Version: 1.0
    Bundle-SymbolicName: com.bajie.test.family.model
    Bundle-Name: family model
    Bundle-Version: 1.0
    Bundle-Vendor: LiMing
    Bundle-Activator: com.bajie.test.family.model.impl.FamilyDatabase
    Import-Package: org.osgi.framework;version=1.3,com.bajie.test.family.model
    Export-Package: com.bajie.test.family.model;version=1.0
    從中我們看到com.bajie.test.family.model這個(gè)package被export出來(lái),這樣其他bundle就能夠import這個(gè)package,并根據(jù)FamilyInfoEntry所提供的基本內(nèi)容提供一些額外的處理結(jié)果,從而產(chǎn)生新列(FamilyInfoColumn)以及排序方法(SortingFamilyInfoCriteria),比如家庭人均年收入。

    下面來(lái)看看gui bundle,它只包含一個(gè)package
    package com.bajie.test.family.gui;
    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.ItemEvent;
    import java.awt.event.ItemListener;
    import java.util.Hashtable;
    import javax.swing.JButton;
    import javax.swing.JComboBox;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import org.osgi.framework.BundleActivator;
    import org.osgi.framework.BundleContext;
    import org.osgi.framework.Constants;
    import org.osgi.framework.ServiceEvent;
    import org.osgi.framework.ServiceListener;
    import org.osgi.framework.ServiceReference;
    import com.bajie.test.family.model.FamilyInfoDatabase;
    import com.bajie.test.family.model.SortingFamilyInfoCriteria;
    public class FamilyInfoGui implements BundleActivator, ActionListener,
            ItemListener, ServiceListener {
        private JFrame mainFrame;
        private JPanel contentPanel;
        private JTable familiesTable;
        private JScrollPane familiesTableScrollPane;
        private JPanel sortedByPanel = new JPanel(new GridLayout(1, 2));
        private JLabel sortedByLabel = new JLabel("Sorted By: ");
        private JComboBox sortedByList = null;
        private JPanel commandPanel = new JPanel(new GridLayout(1, 3));
        private JButton addEntry = new JButton("Add");
        private JButton deleteEntry = new JButton("Delete");
        private JButton updateEntry = new JButton("Update");
        private Hashtable sortingFields = new Hashtable();
        private BundleContext context;
        FamilyInfoDatabase database = null;
        public void start(BundleContext context) throws Exception {
            this.context = context;
            //查找所有注冊(cè)類型為FamilyInfoDatabase的服務(wù)對(duì)象。在我們這個(gè)例子,它是由上面給出的model bundle注冊(cè)的
            ServiceReference databaseServiceRef = context
                    .getServiceReference(FamilyInfoDatabase.class.getName());
            if (databaseServiceRef == null) {
                System.out.println("No database service is registered.");
                return;
            }
     //這個(gè)服務(wù)對(duì)象將成為JTable的數(shù)據(jù)model
            this.database = (FamilyInfoDatabase) context
                    .getService(databaseServiceRef);
            if (this.database == null) {
                System.out.println("Can not get database object");
                return;
            }
            //查找所有注冊(cè)類型為SortingFamilyInfoCriteria的服務(wù)對(duì)象。
            ServiceReference[] sortingCriteria = context.getServiceReferences(
                    SortingFamilyInfoCriteria.class.getName(), null);
            sortedByList = new JComboBox();
            SortingFamilyInfoCriteria criterion = null;
            if (sortingCriteria != null) {
                for (int i = 0; i < sortingCriteria.length; i++) {
                    criterion = (SortingFamilyInfoCriteria) context
                            .getService(sortingCriteria[i]);
                    if (criterion != null) {
          //每個(gè)服務(wù)對(duì)象將對(duì)應(yīng)一種排序方法,并加入到下拉列表中
                        sortedByList.addItem(criterion.getSortFieldString());
                        this.sortingFields.put(criterion.getSortFieldString(),
                                criterion);
                    }
                }
            }
     //注冊(cè)服務(wù)偵聽(tīng)器,該偵聽(tīng)器專門(mén)偵聽(tīng)SortingFamilyInfoCriteria服務(wù)對(duì)象的動(dòng)態(tài)(主要是增加和刪除)
            context.addServiceListener(this, "(" + Constants.OBJECTCLASS + "="
                    + SortingFamilyInfoCriteria.class.getName() + ")");
            sortedByList.addItemListener(FamilyInfoGui.this);
            //construct gui
            Runnable r = new Runnable() {
                public void run() {
                    contentPanel = new JPanel();
                    familiesTableScrollPane = new JScrollPane();
      //獲得的FamilyInfoDatabase對(duì)象成為gui中JTable的model
                    familiesTable = new JTable(database);
                    familiesTableScrollPane.setViewportView(familiesTable);
                    sortedByPanel.add(sortedByLabel);
                    sortedByPanel.add(sortedByList);
                    commandPanel.add(addEntry);
                    commandPanel.add(deleteEntry);
                    commandPanel.add(updateEntry);
                    contentPanel.add(sortedByPanel, BorderLayout.NORTH);
                    contentPanel.add(familiesTableScrollPane, BorderLayout.CENTER);
                    contentPanel.add(commandPanel, BorderLayout.SOUTH);
                    mainFrame = new JFrame();
                    mainFrame.setContentPane(contentPanel);
                    mainFrame.setSize(new Dimension(500, 600));
                    mainFrame.show();
                }
            };
            Thread t = new Thread(r);
            t.start();
        }
        public void stop(BundleContext context) throws Exception {
            if (this.mainFrame != null)
                this.mainFrame.dispose();
        }
        public void actionPerformed(ActionEvent event) {
        }
        public void itemStateChanged(ItemEvent event) {
            if (event.getSource() == this.sortedByList) {
                SortingFamilyInfoCriteria criterion = (SortingFamilyInfoCriteria) this.sortingFields
                        .get(event.getItem());
                if (criterion == null)
                    return;
                this.database.sort(criterion);
                this.familiesTable.repaint();
            }
        }
        public void serviceChanged(ServiceEvent event) {
            switch (event.getType()) {
            case ServiceEvent.MODIFIED:
                return;
            case ServiceEvent.REGISTERED://有新的排序方法注冊(cè)到framework當(dāng)中
                ServiceReference ref = event.getServiceReference();
                SortingFamilyInfoCriteria criterion = (SortingFamilyInfoCriteria) this.context
                        .getService(ref);
                if (criterion != null) {
      //把新的排序方法加入到下拉列表中
                    sortedByList.addItem(criterion.getSortFieldString());
                    this.sortingFields.put(criterion.getSortFieldString(),
                            criterion);
                }
                return;
            case ServiceEvent.UNREGISTERING://一個(gè)現(xiàn)有的排序方法將被從framework被取消
                ref = event.getServiceReference();
                criterion = (SortingFamilyInfoCriteria) this.context
                        .getService(ref);
                if (criterion != null) {
      //把該排序方法從下拉列表中刪除
                    sortedByList.removeItem(criterion.getSortFieldString());
                    this.sortingFields.remove(criterion);
                }
                return;
            }
        }
    }
     
    與(五)相比不同的地方是,這個(gè)gui的table model以及排序的方法,都是通過(guò)查詢service對(duì)象獲得。
     
    manifest文件如下:
    Manifest-Version: 1.0
    Bundle-SymbolicName: com.bajie.test.family.gui
    Bundle-Name: family gui
    Bundle-Version: 1.0
    Bundle-Vendor: LiMing
    Bundle-Activator: com.bajie.test.family.gui.FamilyInfoGui
    Import-Package: org.osgi.framework;version=1.3,com.bajie.test.family.model
     
    然后我們生成bundle的jar文件。分別為familymodel.jar和familygui.jar,之后我們用“in”命令把兩個(gè)bundle裝入framework。
    接著我們先啟動(dòng)model bundle,然后再啟動(dòng)gui bundle,我們會(huì)看到JTable中有3列,而排序方法列表中也有3個(gè)選項(xiàng),完全和程序的邏輯符合。
     
    接下來(lái),我們假設(shè)客戶需要添加顯示每個(gè)家庭的人均年收入并按其排列紀(jì)錄。要滿足這個(gè)需求,我們可以參考在(五)中做法,就是在model bundle里面再添加一個(gè)同時(shí)實(shí)現(xiàn)了FamilyInfoColumn和SortingFamilyInfoCriteria的類,并在bundle的啟動(dòng)中作為服務(wù)注冊(cè)到framework中?不過(guò)這樣就得更新model bundle然后調(diào)用rfr命令來(lái)刷新。為什么不再裝一個(gè)補(bǔ)丁bundle,在這個(gè)bundle中包含了同時(shí)實(shí)現(xiàn)FamilyInfoColumn和SortingFamilyInfoCriteria的類,并在這個(gè)新bunle啟動(dòng)時(shí)注冊(cè)產(chǎn)生該類的新對(duì)象作為服務(wù)注冊(cè)到framework中,這樣gui和model bundle都能偵聽(tīng)到該新服務(wù)的到來(lái)(他們都實(shí)現(xiàn)了服務(wù)偵聽(tīng)接口ServiceListener),gui上馬上就能有所體現(xiàn)。

    這個(gè)新bundle的代碼如下:
    package com.bajie.test.family.model.impladd;
    import org.osgi.framework.BundleActivator;
    import org.osgi.framework.BundleContext;
    import com.bajie.test.family.model.FamilyInfoColumn;
    import com.bajie.test.family.model.FamilyInfoEntry;
    import com.bajie.test.family.model.SortingFamilyInfoCriteria;
    public class FamilyIncomePerPerson implements BundleActivator {
        public void start(BundleContext context) throws Exception {
     //注冊(cè)一個(gè)新的服務(wù),服務(wù)的類型既為FamilyInfoColumn,也是SortingFamilyInfoCriteria
            String[] clazzes = new String[] {FamilyInfoColumn.class.getName(),SortingFamilyInfoCriteria.class.getName()};
            context.registerService(clazzes,new FamilyIncomePerPersonColumn(),null);
           
        }
        public void stop(BundleContext context) throws Exception {
        }
        //這個(gè)類實(shí)現(xiàn)了“Income Per Person”這個(gè)列以及按該列排序的方法。
        class FamilyIncomePerPersonColumn implements FamilyInfoColumn,SortingFamilyInfoCriteria {
            private static final String COLUMNNAME = "Income Per Person";
           
            public Object getColumnValue(FamilyInfoEntry entry) {
                return new Integer(entry.getIncomePerYear()/entry.getPopulation());
            }
           
           
            public String getColumnName() {
                return FamilyIncomePerPersonColumn.COLUMNNAME;
            }
           
            public String getSortFieldString() {
                return FamilyIncomePerPersonColumn.COLUMNNAME;
            }
            public int compare(Object obj1, Object obj2) {
                if (obj1 == obj2) {
                    return 0;
                }
                FamilyInfoEntry en1 = (FamilyInfoEntry)obj1;
                FamilyInfoEntry en2 = (FamilyInfoEntry)obj2;
               
                return en1.getIncomePerYear()/en1.getPopulation() - en2.getIncomePerYear()/en2.getPopulation();
            }
           
        }
    }
     
    manifest文件如下:
    Manifest-Version: 1.0
    Bundle-SymbolicName: com.bajie.test.family.modeladd
    Bundle-Name: family model add
    Bundle-Version: 1.0
    Bundle-Vendor: LiMing
    Bundle-Activator: com.bajie.test.family.model.impladd.FamilyIncomePerPerson
    Import-Package: org.osgi.framework;version=1.3,com.bajie.test.family.model
     
    打包安裝到framework后,啟動(dòng)該bundle,我們就會(huì)在gui上看到新的列已經(jīng)被添加,而且排序列表中增加了一個(gè)新的排序選項(xiàng)。
    這個(gè)結(jié)果,完全符合需求的意圖。
    如果我們用stp命令停止這個(gè)bundle,我們?cè)趃ui上就會(huì)發(fā)現(xiàn),新列消失,而且排序列表中對(duì)應(yīng)選項(xiàng)也沒(méi)有了。這就是service帶來(lái)的動(dòng)態(tài)效果。不過(guò),如果我們的model發(fā)生了一些實(shí)質(zhì)的變化,比如FamilyInfoEntry需要添加一個(gè)“地址”列,那么model bundle就要更新,進(jìn)而gui bundle以及使用到這個(gè)類型的bundle都需要通過(guò)rfr命令刷新。
     
    好了,對(duì)扶貧助手的分析就此打住,我們總結(jié)一下,通過(guò)程序可以看到注冊(cè)服務(wù)一點(diǎn)都不復(fù)雜。最簡(jiǎn)單的情況我們只需要提供一個(gè)java類型名稱,以及實(shí)現(xiàn)這個(gè)類型的一個(gè)java對(duì)象就可以了,
    不需要提供復(fù)雜的類型描述,比如xml描述文件。而使用服務(wù)的bundle通過(guò)類型名稱就輕而易舉的查找到相關(guān)的服務(wù)對(duì)象。
     
    到此,osig介紹系列就要結(jié)束了,只希望這個(gè)系列能夠把你引入到osgi的門(mén)口,其后面的精彩世界就看你的興趣了。
    就我個(gè)人的關(guān)注和理解,今年是osgi很重要的一年。JSR249今年應(yīng)該投票,如果osgi入選,那么osgi將成為高端手機(jī)中java體系結(jié)構(gòu)的重要組成部分。
    在汽車(chē)領(lǐng)域,siemensVDO已經(jīng)推出了基于osgi的解決方案,聽(tīng)說(shuō)已經(jīng)配備在BMW serials 5里面了。應(yīng)該還會(huì)有更多的應(yīng)用......
     
    如果你是osgi的粉絲,歡迎你來(lái)信jerrylee.li@gmail.com拍磚交流。

    posted on 2006-02-14 16:08 勤勞的蜜蜂 閱讀(5957) 評(píng)論(13)  編輯  收藏

    評(píng)論

    # re: OSGi介紹(六)OSGi的service 2006-02-15 09:50 BlueDavy

    ^_^,現(xiàn)在注冊(cè)服務(wù)以及使用服務(wù)的部分在osgi中還是不那么方便的,注入會(huì)讓它變得更加方便,其實(shí)好像ds是解決了部分,但還沒(méi)完全做到注入..  回復(fù)  更多評(píng)論   

    # re: OSGi介紹(六)OSGi的service 2006-02-15 12:36 勤勞的蜜蜂

    ds是什么?有相關(guān)的比較文章嗎?我看看,謝謝。  回復(fù)  更多評(píng)論   

    # re: OSGi介紹(六)OSGi的service 2006-02-15 13:15 BlueDavy

    OSGI中的Declartive Service  回復(fù)  更多評(píng)論   

    # re: OSGi介紹(六)OSGi的service 2006-02-15 13:21 勤勞的蜜蜂

    哦,它呀。正在研究中,聽(tīng)說(shuō)是extension point的替代品  回復(fù)  更多評(píng)論   

    # re: OSGi介紹(六)OSGi的service[未登錄](méi) 2007-04-16 17:48 andy

    謝啦 樓主好幸苦 不過(guò)感覺(jué)這個(gè)例子太長(zhǎng) 看起來(lái)有點(diǎn)費(fèi)勁 最好能找個(gè)簡(jiǎn)單一點(diǎn)的 大家看著方便 不知道您對(duì)ds有什么看法 我的郵箱是qmiao128@163.com 可以交流一下嗎  回復(fù)  更多評(píng)論   

    # re: OSGi介紹(六)OSGi的service 2007-06-22 11:59 hata

    太長(zhǎng)了 看暈了.沒(méi)理解service的機(jī)制.
    繼續(xù)看看...暈暈了.  回復(fù)  更多評(píng)論   

    # re: OSGi介紹(六)OSGi的service 2007-07-05 15:36 guyong

    context.addServiceListener(this,"(" + Constants.OBJECTCLASS + "=" + FamilyInfoColumn.class.getName() + ")");
    請(qǐng)問(wèn)一下這個(gè)給bundle添加監(jiān)聽(tīng)的方法中的第二個(gè)參數(shù)是什么意思?格式是固定的嗎?謝謝!
    我的郵箱:guyong1018@yahoo.com.cn  回復(fù)  更多評(píng)論   

    # re: OSGi介紹(六)OSGi的service 2007-07-06 13:49 ferrari4000

    第二個(gè)參數(shù)的意思是,這個(gè)listener只偵聽(tīng)服務(wù)對(duì)象滿足 instanceof(FamilyInfoColumn.class) == true的ServiceEvent.
    當(dāng)有服務(wù)事件發(fā)生時(shí),Framework會(huì)給每個(gè)注冊(cè)的listener發(fā)送消息,但是,如果服務(wù)注冊(cè)的時(shí)候,有過(guò)濾條件,它會(huì)先檢查這個(gè)事件是否滿足這個(gè)過(guò)濾條件,如果不滿足,那這個(gè)事件就不會(huì)發(fā)送到這個(gè)listener.

    osgi spec里面對(duì)這個(gè)格式進(jìn)行了定義.請(qǐng)看第37頁(yè)@r4.core.pdf version4.01 July 6, 2006版
      回復(fù)  更多評(píng)論   

    # re: OSGi介紹(六)OSGi的service 2007-09-25 09:55 hello

    太長(zhǎng)了,很難看得懂,感覺(jué)!
    看了幾次都看不下去!
      回復(fù)  更多評(píng)論   

    # re: OSGi介紹(六)OSGi的service 2008-07-25 10:16 mhoudg

    汗……
    樓主寫(xiě)了這么多,都沒(méi)喊辛苦
    反倒是來(lái)學(xué)習(xí)的人們一個(gè)勁喊長(zhǎng)喊累……
    這世道……  回復(fù)  更多評(píng)論   

    # re: OSGi介紹(六)OSGi的service 2008-10-31 00:03 bacuo

    不錯(cuò)不錯(cuò),感謝樓主的辛勤勞動(dòng)  回復(fù)  更多評(píng)論   

    # re: OSGi介紹(六)OSGi的service[未登錄](méi) 2008-11-19 11:00 rex

    非常感謝作者的工作!  回復(fù)  更多評(píng)論   

    # re: OSGi介紹(六)OSGi的service[未登錄](méi) 2008-12-12 15:07 mark

    看后受益匪淺,非常感謝樓主  回復(fù)  更多評(píng)論   


    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲av中文无码乱人伦在线播放 | 国产亚洲成归v人片在线观看| 性感美女视频在线观看免费精品| 最近免费中文字幕大全免费版视频| 午夜网站在线观看免费完整高清观看 | 午夜免费福利在线观看| 久久WWW免费人成人片| 国拍在线精品视频免费观看| 美女视频黄的全免费视频 | 美女网站在线观看视频免费的| 亚州**色毛片免费观看| 一个人免费观看视频在线中文| 中文字幕视频在线免费观看| 国产免费拔擦拔擦8X高清在线人 | 国产精品黄页免费高清在线观看| 国产免费一区二区三区免费视频| 手机看片国产免费永久| 国产一级淫片a免费播放口| 一级毛片成人免费看免费不卡| 中文字幕在线观看免费视频| 国产人成免费视频网站| 久久WWW色情成人免费观看| 国产免费无遮挡精品视频 | 男人的好免费观看在线视频| 毛片大全免费观看| 在线观看永久免费视频网站| 亚洲精品和日本精品| 好看的亚洲黄色经典| 亚洲最大视频网站| 亚洲AV无码成人精品区狼人影院| 无人视频免费观看免费视频| a视频在线免费观看| h在线观看视频免费网站| 黄网址在线永久免费观看 | 亚洲日韩精品一区二区三区| 亚洲韩国—中文字幕| 午夜在线a亚洲v天堂网2019| 国产精品久久久久久亚洲小说| 国精产品一区一区三区免费视频| 最近中文字幕mv免费高清在线| 女人被免费视频网站|