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

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

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

    kooyee ‘s blog

    開源軟件, 眾人努力的結(jié)晶, 全人類的共同財(cái)富
    posts - 103, comments - 55, trackbacks - 0, articles - 66
       :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

    [WEB] MetaData Programme

    Posted on 2007-12-01 20:36 kooyee 閱讀(752) 評(píng)論(0)  編輯  收藏 所屬分類: Java

    MetaData Programme

    1.1.        什么是元數(shù)據(jù)編程

    什么是元數(shù)據(jù),元數(shù)據(jù)就是描述數(shù)據(jù)的數(shù)據(jù)(data about data)。最明顯的例子是XML Schemaxml schema就是描述xml的數(shù)據(jù),所以它是元數(shù)據(jù)。另一個(gè)例子是數(shù)據(jù)庫,比如我們可以查詢數(shù)據(jù)庫中有幾個(gè)表,每個(gè)表都有什么字段,這些數(shù)據(jù)就是元數(shù)據(jù)。Office:office" />

    在開發(fā)的世界里,元數(shù)據(jù)就是能夠綁定到一個(gè)類的附加信息,在靜態(tài)或者運(yùn)行時(shí)間。JCR175給我們提供annotation就是一種元數(shù)據(jù)。

    不過在這之前一個(gè)我們已經(jīng)廣泛使用的元數(shù)據(jù)是XML,如就是EJBXML發(fā)布描述符中,你需要定義基于每一個(gè)方法的事務(wù)屬性。應(yīng)用服務(wù)器指導(dǎo)什么時(shí)候,什么地方開始,掛起或者提交一個(gè)事務(wù),因?yàn)槟阍?/span>BEANXML的配置文件中的元數(shù)據(jù)內(nèi)已經(jīng)定義如方法:RequiredRequiresNewSupport等等,它們綁定在你的EJB類和事務(wù)管理之間。XDoclet是另一個(gè)元數(shù)據(jù)的例子。

    1.2.        Annotation的意義和簡單例子

           JDK1.5提供的annotation與我們所常見的classesfieldssmethods間是什么關(guān)系。如下:如果說類和數(shù)據(jù)成員是名詞,方法是動(dòng)詞,那么annotation就是形容詞或者副詞,分別描述它們的所具有屬性。

       好,現(xiàn)在就來實(shí)現(xiàn)一個(gè)annotation

     

    import Java.lang.annotation.Retention;

    package sample.annotation;

    @Retention(java.lang.annotation.RetentionPolicy.RUNTIME)

        
    public @interface Broker {

        String name();

        String address();

        }


    }

     

    使用這個(gè)annotation

    Import sample.annotation.broker;

    @Broker(name
    ="anders", address="xiamen")

    public class Agent {

        
    public String getTelPhone (){

            
    return "010-0592-2519280";

        }


    }


    運(yùn)行期得到這個(gè)annotation

    public class Main {

        
    public static void main(String[] args){

    Agent agent 
    = new Agent();

            
    try{

                Annotation[] a 
    = agent.getClass().getMethod("getBrokerName").getAnnotations();

                
    for (int i=0; i<a.length ; i++{

                     
    if( a[i] instanceof Broker){

                          Broker broker 
    = (Broker)a[i];

                         System.out.println(broker.name());

                     }


                 }


            }


            
    catch(Exception e){

                e.printStackTrace(System.out);

            }


       }


    }




    1.3.
            Annotationclass文件格式

           利用sun公司的提供的javap,我們可以看到annotation的在class文件中的表示。以下為對(duì)比結(jié)果:

    源碼

     

    @Retention(java.lang.annotation.RetentionPolicy.RUNTIME)

    public @interface Broker {

        String name();

        String address();

    }

     

    Javap結(jié)果:

    Compiled from "Broker.java"

    interface Broker extends java.lang.annotation.Annotation

     SourceFile: "Broker.java"

     minor version: 0

     major version: 0

     Constant pool:

    const #1 = class    #9; // Broker

    const #2 = class    #10; // Object

    const #3 = class    #11; //Annotation

    const #4 = Asciz    name;

    const #5 = Asciz   ()Ljava/lang/String;;

    const #6 = Asciz    address;

    const #7 = Asciz    SourceFile;

    const #8 = Asciz    Broker.java;

    const #9 = Asciz    Broker;

    const #10 = Asciz   java/lang/Object;

    const #11 = Asciz   java/lang/annotation/Annotation;

    {

    public abstract java.lang.String name();

    public abstract java.lang.String address();

    }  

    源碼:

    @Broker(name="anders", address="xiamen")

    public class Agent {

        
    public String getTelPhone(){

            
    return "0592-2519580";

        }


    }


    Javap結(jié)果:

    Compiled from "Agent.java"

    public class Agent extends java.lang.Object

     SourceFile: "Agent.java"

     RuntimeVisibleAnnotations: length = 0x10

       00 01 00 11 00 02 00 12 73 00 13 00 14 73 00 15

      

     minor version: 0

     major version: 0

     Constant pool:

    const #1 = Method   #4.#22;// java/lang/Object."<init>":()V

    const #2 = String   #23;    // 0592-2519580

    const #3 = class    #24;    // Agent

    const #4 = class    #25;    // Object

    const #5 = Asciz    <init>;

    const #6 = Asciz    ()V;

    const #7 = Asciz    Code;

    const #8 = Asciz    LineNumberTable;

    const #9 = Asciz    LocalVariableTable;

    const #10 = Asciz   this;

    const #11 = Asciz   LAgent;;

    const #12 = Asciz   getTelPhone;

    const #13 = Asciz   ()Ljava/lang/String;;

    const #14 = Asciz   SourceFile;

    const #15 = Asciz   Agent.java;

    const #16 = Asciz   RuntimeVisibleAnnotations;

    const #17 = Asciz   LBroker;;

    const #18 = Asciz   name;

    const #19 = Asciz   anders;

    const #20 = Asciz   address;

    const #21 = Asciz   xiamen;

    const #22 = NameAndType#5:#6;// "<init>":()V

    const #23 = Asciz   0592-2519580;

    const #24 = Asciz   Agent;

    const #25 = Asciz   java/lang/Object;

    // 以下為方法域,略  

    補(bǔ)充說明:我們都知道在java 1.0發(fā)布時(shí),java class file的格式就已經(jīng)定下來,要說明的是為了應(yīng)未來的需要java class file設(shè)計(jì)了屬性說的機(jī)制。一直到J2SE1.4都沒有怎么改變。但這次為了更好的支持metadata技術(shù),一共增加了8個(gè)屬性。分別是:

    EnclosingMethodAttribute Anonymous Class Local Inner Class 使用此 Attribute 描述該Class Scope

    Signature AttributeGenerics ClassMethod、或 Filed使用此 Attribute 來記錄所要的類型,因?yàn)?/span>java的范型采用了擦拭法。

    LocalVariableTypeTable Attribute:主要是給 debugger 使用,目的和「LocalVariableTable Attribute類似,只是「LocalVariableTable Attribute 記錄所要的參數(shù)表,而「LocalVariableTypeTable Attribute 記錄參數(shù)的類型。

    RuntimeVisibleAnnotations Attribute:確定該annotation可以被reflectionAPI返回,適用對(duì)象:ClassMethodField

    RuntimeInvisibleAnnotations Attribute:確定該annotation無法被reflectionAPI返回,適用對(duì)象: ClassMethodField 

    RuntimeVisibleParameterAnnotations Attribute:同「RuntimeVisibleAnnotations Attribute,適用對(duì)象:Method,(該Method 的參數(shù)

    RuntimeInvisibleParameterAnnotations Attribute:同「RuntimeInvisibleAnnotations Attribute,適用對(duì)象:Method,(該Method 的參數(shù)。

    AnnotationDefault Attribute:適用對(duì)象:Method,記錄默認(rèn)值。

    1.4.        為什么需要Annotation

           annotation之前我們已經(jīng)廣泛使用另外一種元數(shù)據(jù)xml,為什么需要annotationAnnotationxml的作為元數(shù)據(jù)的區(qū)別是什么——位置。Annotation寫在源代碼中,而xml寫在外部。

           為什么要這樣?如果你開發(fā)EJB,你一定為你的EJB寫過xml描述文件。當(dāng)大量的EJB需要描述時(shí),就出現(xiàn)了所謂的"descriptor hell"。這個(gè)也導(dǎo)致了著名的XDoclet的出現(xiàn)。而annotation出現(xiàn)可以避免這種descriptor hell。另外你更改了某個(gè)方法為其增加或者減少一個(gè)參數(shù),你就對(duì)應(yīng)的修改xml文件,而使用annotation則不必。使用annotation將開發(fā)和部署更方便,提供開發(fā)效率。

           另外:使用xml的另一個(gè)問題是:很多Xml配置太過verbose。相比較EJBHibernate 或者Webwork可以明顯的發(fā)現(xiàn)不同。

    1.5.        再議Annotation

    EJB3中,Annotation把開發(fā)和部署的工作合在一起。但是在一些企業(yè)環(huán)境中,開發(fā)人員并不控制諸如數(shù)據(jù)源名等(這些是部署部門和管理部門的工作),這樣把數(shù)據(jù)源名寫在xml中將比較好。

           Annotation是本身靜態(tài)的,一旦添加或者修改annotation都需要重新編譯,在運(yùn)行時(shí)讀取,這樣就喪失了運(yùn)行時(shí)配置的能力。因此Annotations 不會(huì)取代xml,它只是提供了另一種途徑。并且我相信sun公司將在未來提供一個(gè)方式可以在運(yùn)行期更改metadata

    關(guān)于這點(diǎn)TSS上有著很激烈的討論,很多開發(fā)人員提出:利用xml來更改annotation,并希望類似的方式能被采納為標(biāo)準(zhǔn)規(guī)范。比如使用如下格式:

     

    <class name="org.hibernate.Item">

    @Entity

        @Table(name="AUCTION_ITEM")

        
    <method sig="getBar()">@Transient</method>

        
    <method sig="doSomething(int, String)">

            @Tx(REQUIRES_NEW)

        
    </method>

    </class>

     

     當(dāng)然也有不同意見:But then, I think of "overriding" as a different problem to "xml deployment descriptors", and so I think we need two solutions. I think Cedric and Bill are trying to kill two birds with one stone, so maybe their proposals are better....

    關(guān)于為annotation提供動(dòng)態(tài)配置能力的問題,其中一個(gè)網(wǎng)友認(rèn)為:Sun make it real pain to do the deployment XML so that they can introduce annotation to fix it. The annotation can make code/deployment coupling so strong that Sun can come out with a new way (annotation interceptor in jdk 1.6? :)) for fixing it. and the cycles goes on...這讓我想起了類似的現(xiàn)象:JSPTagLib。希望Annotation不會(huì)和TagLib有同樣的命運(yùn)。

           Annotation本身引入另一種類型的接口。在EJB3中確實(shí)使程序更加POJO,也消除了一些接口。并且編譯后的代碼也可以直接移植到另一個(gè)并不處理這些annotations的環(huán)境中(感謝VM在加載類時(shí)并不檢查那些annotationsclasses,甚至這些類不在classpath中)。然而代碼也確實(shí)增加了另一些接口。這個(gè)表現(xiàn)在編譯期,如果沒有這些annotation classes,是編譯不過的。

           另一個(gè)問題(還好不算很重要),關(guān)于annotationnamespace。在多層應(yīng)用的系統(tǒng)中,可能會(huì)出現(xiàn)同樣的全局annotationnamespace沖突。比如一些公共的annotation,如@Transaction,將會(huì)被應(yīng)用在很多個(gè)層次中。盡量讓namespace長些,可以避免這個(gè)問題。

    1.6.        元數(shù)據(jù)編程的應(yīng)用:

    Annotation已經(jīng)被集成到很多的java規(guī)范和標(biāo)準(zhǔn)中,很重要的是它已經(jīng)被J2EE標(biāo)準(zhǔn),如EJB3所采用,當(dāng)然也被許多開源的組件體系如:ASPectJ

           Annotation最重要的應(yīng)用將是AOP:由于annotation可以天然的表示系統(tǒng)中的另一個(gè)橫切面,同時(shí)Annotation的識(shí)別是通過反射得到的,所以Annotation很自然的應(yīng)用到基于動(dòng)態(tài)代理的AOP實(shí)現(xiàn)。AOPAlliance也支持metadata handlingAspectJ也發(fā)布了基于annotation的新版本。

           在實(shí)現(xiàn)AOP上,使用annotation也比使用XML有一個(gè)優(yōu)勢:如前所述,annotation更像是形容詞和副詞,這樣比較不容易verbose。當(dāng)然這個(gè)是相對(duì)的,在實(shí)際的實(shí)現(xiàn)中更依賴開發(fā)人員的努力。

           這里,筆者將展示一個(gè)不完整也不成熟的基于annotationAOP例子代碼——關(guān)于銀行卡的例子。

           功能需求:銀行卡業(yè)務(wù)分為轉(zhuǎn)帳,查詢余額,查詢明細(xì),POS消費(fèi)等。這其中轉(zhuǎn)帳和POS消費(fèi)是要收費(fèi)的(轉(zhuǎn)帳收取的是用戶的手續(xù)費(fèi),而POS消費(fèi)收取的是商家的手續(xù)費(fèi)),另外POS消費(fèi)還可能有積分的(比如筆者的牡丹貸記卡)。消費(fèi)轉(zhuǎn)帳都要記錄明細(xì)。但查詢余額就不需要記錄在明細(xì)中。

           代碼如下(在這個(gè)例子沒有用動(dòng)態(tài)代理也沒有用已有的AOP框架,使代碼看起來簡單些)

      1// 銀行卡對(duì)象
      2
      3public class Card {
      4
      5    private String account; 
      6
      7//some field method
      8
      9}

     10
     11Annotation:
     12
     13// 手續(xù)費(fèi)
     14
     15// type= "user", 表示收取用戶手續(xù)費(fèi); type= "Biz", 表示收取商家手續(xù)費(fèi)
     16
     17public @interface Fee{
     18
     19    String type();
     20
     21}

     22
     23// 積分
     24
     25public @interface Index {
     26
     27}

     28
     29// 記錄明細(xì)
     30
     31public @interface BizLog {
     32
     33}

     34
     35// 事務(wù)處理
     36
     37public @interface Transaction {
     38
     39}

     40
     41// 業(yè)務(wù)接口
     42
     43public interface BizAction {
     44
     45    void execute(Card card, RunData rundata);
     46
     47}

     48
     49// 轉(zhuǎn)帳業(yè)務(wù)
     50
     51@Fee(type="user")
     52
     53@Transaction
     54
     55@BizLog
     56
     57public class TransferAction implements BizAction {
     58
     59    public void execute(Card card, RunData rundata) {
     60
     61        //To change body of implemented methods use File | Settings | File Templates.
     62
     63    }

     64
     65}

     66
     67// POS消費(fèi)
     68
     69@Fee(type="Biz")
     70
     71@Transaction
     72
     73@BizLog
     74
     75@Index
     76
     77public class POSAction implements BizAction {
     78
     79    public void execute(Card card, RunData rundata) {
     80
     81        //To change body of implemented methods use File | Settings | File Templates.
     82
     83    }

     84
     85}

     86
     87// 查詢明細(xì)
     88
     89public class QueryDetail implements BizAction {    
     90
     91    public void execute(Card card, RunData rundata) {
     92
     93        //To change body of implemented methods use File | Settings | File Templates.
     94
     95    }

     96
     97}

     98
     99// 業(yè)務(wù)操作監(jiān)視器接口
    100
    101public interface BizActionMonitor {
    102
    103   void execute(BizAction action, RunData rundata);
    104
    105}

    106
    107// 業(yè)務(wù)操作監(jiān)視器實(shí)現(xiàn)
    108
    109public class BizActionMonitorImpl implements BizActionMonitor{
    110
    111    public void execute(BizAction action, RunData rundata) {
    112
    113        Annotation[] annotations = action.getClass().getAnnotations();
    114
    115        for(Annotation annotation : annotations){
    116
    117            if (annotation instanceof Fee)// 計(jì)算手續(xù)費(fèi)   }
    118
    119            if (annotation instanceof Index)//計(jì)算積分    }
    120
    121            if (annotation instanceof Transaction)// 準(zhǔn)備事務(wù) }
    122
    123            if (annotation instanceof BizLog)// 記錄明細(xì)   }
    124
    125        }

    126
    127    }

    128
    129}

    130
    131// 控制器對(duì)象
    132
    133public class controller{
    134
    135    private BizActionMonitor monitor;   
    136
    137    public void execute(BizActionUI, rundata){
    138
    139        BizAction action = getAction(BizActionUI);      
    140
    141        monitor.execute(action, rundata);
    142
    143    }

    144
    145}

    146
    147// 運(yùn)行時(shí)數(shù)據(jù)
    148
    149public interface RunData {
    150
    151   // some method
    152
    153}

    154
    155// 用戶設(shè)備(POS機(jī), ATM或者柜臺(tái)終端)接口
    156
    157public class BizActionUI {
    158
    159      private RunData rundata;
    160
    161      private Controller controller;
    162
    163      public BizActionUI(RunData rundata, Controller controller){
    164
    165          this.rundata = rundata;
    166
    167          this.controller = controller;
    168
    169      }

    170
    171      public void execute()// 某個(gè)子類實(shí)現(xiàn) }
    172
    173      public void commit(){
    174
    175          controller.execute(this, rundata);
    176
    177      }

    178
    179}

    180
    181public class Main{
    182
    183    private Rundata rundata;
    184
    185    private Controller controller; 
    186
    187    public populateUI(command){
    188
    189        BizActionUI ui = getUI(command);
    190
    191        ui.execute();
    192
    193    }
       
    194
    195    public BizActionUI getUI(command){
    196
    197        //
    198
    199        BizActionUI ui 
    200
    201        if//.){
    202
    203            ui = new SomeBizActionUI(rundata, controller);
    204
    205        }

    206
    207        return ui;      
    208
    209    }
        
    210
    211    public static main(String[] args){
    212
    213        //
    214
    215        Main main = new Main();
    216
    217        main.populateUI(command)
    218
    219        //
    220
    221    }

    222
    223}

    224
    225

    1.7.
            結(jié)束語:

    本文討論了annotation技術(shù),展示了annotationclass文件格式,并討論了annotation技術(shù)本身的優(yōu)勢和不足,并于現(xiàn)有的xml技術(shù)加以比較,展望了annotation技術(shù)的應(yīng)用前景AOP

    限于筆者自身的水平(包括技術(shù)水平和寫作水平),技術(shù)上對(duì)annotation的學(xué)習(xí)比較有限,寫作上也感覺好多話無法用文字來表達(dá),因而本文的代碼會(huì)比較多(大概有一半以上)。

    主站蜘蛛池模板: 亚洲爆乳大丰满无码专区 | 黄+色+性+人免费| 精品国产免费人成电影在线观看| 色老头永久免费网站| 中文字幕亚洲激情| 亚洲成色WWW久久网站| 久久久久亚洲av无码专区导航| 亚洲国产日产无码精品| 亚洲精华液一二三产区| 亚洲一区在线免费观看| 亚洲精品高清无码视频| 亚洲性猛交xx乱| 亚洲一卡2卡三卡4卡无卡下载| 午夜亚洲国产精品福利| 久久国产精品免费一区| 日韩免费高清大片在线| 最近2019中文字幕免费看最新 | 亚洲日韩国产AV无码无码精品| 人人鲁免费播放视频人人香蕉 | 亚洲啪啪免费视频| 亚洲va无码专区国产乱码| 亚洲卡一卡二卡乱码新区| jizz免费观看| 日本一区二区三区免费高清| 精品国产人成亚洲区| 美女尿口扒开图片免费| 最近免费中文字幕大全高清大全1 最近免费中文字幕mv在线电影 | 一级毛片免费视频网站| 久久国产免费福利永久| 久久综合亚洲色一区二区三区| 男女超爽视频免费播放| 暖暖免费高清日本中文| 中文国产成人精品久久亚洲精品AⅤ无码精品 | 欧洲精品码一区二区三区免费看 | 在线观看免费成人| 亚洲国产精华液网站w| 中文字幕手机在线免费看电影| 欧美好看的免费电影在线观看| 亚洲国产精品久久网午夜| www视频免费看| 亚洲天堂一区在线|