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

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

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

    xylz,imxylz

    關注后端架構、中間件、分布式和并發編程

       :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      111 隨筆 :: 10 文章 :: 2680 評論 :: 0 Trackbacks

    1.3 更多話題

    1.3.1 接口多實現

    如果一個接口有多個實現,這樣通過@Inject和Module都難以直接實現,但是這種現象確實是存在的,于是Guice提供了其它注入方式來解決此問題。比如下面的自定義注解。


    1     public interface Service {
    2 
    3         void execute();
    4     }
    5 
    6 

    1 public class HomeService implements Service {
    2     @Override
    3     public void execute() {
    4         System.out.println("home.imxylz.cn");
    5     }
    6 }

    1 public class WwwService implements Service {
    2     @Override
    3     public void execute() {
    4         System.out.println("www.imxylz.cn");
    5     }
    6 }

    1 @Retention(RetentionPolicy.RUNTIME)
    2 @Target({FIELD,PARAMETER})
    3 @BindingAnnotation
    4 public @interface Home {
    5 }

    1 @Retention(RetentionPolicy.RUNTIME)
    2 @Target({FIELD,PARAMETER})
    3 @BindingAnnotation
    4 public @interface Www {
    5 }

    上面的代碼描述的是一個Service服務,有WwwService和HomeService兩個實現,同時有Www和Home兩個注解(如果對注解各個參數不明白的需要單獨去學習JAVA 5注解)。好了下面請出我們的主角。
     1     /**
     2      * $Id: MultiInterfaceServiceDemo.java 82 2009-12-24 06:55:16Z xylz $
     3      * xylz study project (www.imxylz.cn)
     4      */
     5     package cn.imxylz.study.guice.inject.more;
     6 
     7     import com.google.inject.Binder;
     8     import com.google.inject.Guice;
     9     import com.google.inject.Inject;
    10     import com.google.inject.Module;
    11 
    12     /** a demo with multi interfaces
    13      * @author xylz (www.imxylz.cn)
    14      * @version $Rev: 82 $
    15      */
    16     public class MultiInterfaceServiceDemo {
    17         @Inject
    18         @Www
    19         private Service wwwService;
    20         @Inject
    21         @Home
    22         private Service homeService;
    23         public static void main(String[] args) {
    24             MultiInterfaceServiceDemo misd = Guice.createInjector(new Module() {
    25                 @Override
    26                 public void configure(Binder binder) {
    27                     binder.bind(Service.class).annotatedWith(Www.class).to(WwwService.class);
    28                     binder.bind(Service.class).annotatedWith(Home.class).to(HomeService.class);
    29                 }
    30             }).getInstance(MultiInterfaceServiceDemo.class);
    31             misd.homeService.execute();
    32             misd.wwwService.execute();
    33         }
    34     }
    35 
    36 

    此類的結構是注入兩個Service服務,其中wwwService是注入@Www注解關聯的WwwService服務,而homeService是注入@Home注解關聯的HomeService服務。

    同樣關于此結構我們要問幾個問題。

    問題(1)靜態注入多個服務怎么寫?

    其實,參照教程02,我們可以使用下面的例子。


     1 public class StaticMultiInterfaceServiceDemo {
     2     @Inject
     3     @Www
     4     private static Service wwwService;
     5     @Inject
     6     @Home
     7     private static Service homeService;
     8     public static void main(String[] args) {
     9        Guice.createInjector(new Module() {
    10             @Override
    11             public void configure(Binder binder) {
    12                 binder.bind(Service.class).annotatedWith(Www.class).to(WwwService.class);
    13                 binder.bind(Service.class).annotatedWith(Home.class).to(HomeService.class);
    14                 binder.requestStaticInjection(StaticMultiInterfaceServiceDemo.class);
    15             }
    16         });
    17         StaticMultiInterfaceServiceDemo.homeService.execute();
    18         StaticMultiInterfaceServiceDemo.wwwService.execute();
    19     }
    20 }

    問題(2):如果不小心一個屬性綁定了多個接口怎么辦?

    非常不幸,你將得到類似一下的錯誤,也就是說不可以綁定多個服務。


    1) cn.imxylz.study.guice.inject.more.StaticMultiInterfaceServiceDemo.wwwService has more than one annotation annotated with @BindingAnnotation: cn.imxylz.study.guice.inject.more.Www and cn.imxylz.study.guice.inject.more.Home
      at cn.imxylz.study.guice.inject.more.StaticMultiInterfaceServiceDemo.wwwService(StaticMultiInterfaceServiceDemo.java:
    17)

    問題(3):我太懶了不想寫注解來區分多個服務,怎么辦?

    程序員都是懶惰的,于是Google幫我們提供了一個Names的模板來生成注解??聪旅娴睦印?/p>

     1 public class NoAnnotationMultiInterfaceServiceDemo {
     2     @Inject
     3     @Named("Www")
     4     private static Service wwwService;
     5     @Inject
     6     @Named("Home")
     7     private static Service homeService;
     8     public static void main(String[] args) {
     9        Guice.createInjector(new Module() {
    10             @Override
    11             public void configure(Binder binder) {
    12                 binder.bind(Service.class).annotatedWith(Names.named("Www")).to(WwwService.class);
    13                 binder.bind(Service.class).annotatedWith(Names.named("Home")).to(HomeService.class);
    14                 binder.requestStaticInjection(NoAnnotationMultiInterfaceServiceDemo.class);
    15             }
    16         });
    17         NoAnnotationMultiInterfaceServiceDemo.homeService.execute();
    18         NoAnnotationMultiInterfaceServiceDemo.wwwService.execute();
    19     }
    20 }

    上面的例子中我們使用Named來標注我們的服務應該使用什么樣的注解,當然前提是我們已經將相應的服務與注解關聯起來了。

    1.3.2 Provider注入

    在教程第一篇中我們提到了可以通過Provider注入一個服務,這里詳細說說這種模式。

    首先我們需要構造一個Provider<T>出來。


    1     public class WwwServiceProvider implements Provider<Service> {
    2 
    3         @Override
    4         public Service get() {
    5             return new WwwService();
    6         }
    7     }
    8 
    9 

    上面的Provider的意思很簡單,每次新建一個新的WwwService對象出來。

    注入的過程看下面的代碼。


     1     public class ProviderServiceDemo {
     2 
     3         @Inject
     4         private Service service;
     5 
     6         public static void main(String[] args) {
     7             Injector inj=  Guice.createInjector(new Module() {
     8                 @Override
     9                 public void configure(Binder binder) {
    10                     binder.bind(Service.class).toProvider(WwwServiceProvider.class);
    11                 }
    12             });
    13             ProviderServiceDemo psd = inj.getInstance(ProviderServiceDemo.class);
    14             psd.service.execute();
    15         }
    16 
    17     }
    18 
    19 

    很顯然如果這東西和線程綁定就非常好了,比如我們可以使用ThreadLocal來做線程的對象交換。

    當然如果想自動注入(不使用Module手動關聯)服務的話,可以使用@ProviderBy注解。


    1     @ProvidedBy(WwwServiceProvider.class)
    2     public interface Service {
    3 
    4         void execute();
    5     }
    6 
    7 

    這樣我們就不必使用Module將Provider綁定到Service上,獲取服務就很簡單了。


    ProviderServiceDemo psd = Guice.createInjector().getInstance(ProviderServiceDemo.class);
    psd.service.execute();

    除了上述兩種方式我們還可以注入Provider,而不是注入服務,比如下面的例子例子中,屬性不再是Service,而是一個Provider<Service>。


     1     public class ProviderServiceDemo {
     2 
     3         @Inject
     4         private Provider<Service> provider;
     5 
     6         public static void main(String[] args) {
     7             ProviderServiceDemo psd = Guice.createInjector(new Module() {
     8                 @Override
     9                 public void configure(Binder binder) {
    10                     binder.bind(Service.class).toProvider(WwwServiceProvider.class);
    11                 }
    12             }).getInstance(ProviderServiceDemo.class);
    13             psd.provider.get().execute();
    14         }
    15     }
    16 
    17 

    當然了,由于我們WwwServiceProvider每次都是構造一個新的服務出來,因此在類ProviderServiceDemo中的provider每次獲取的服務也是不一樣的。

    1.3.3 綁定常量

    看看下面的例子,演示了一個綁定整數值到實例的例子。


     1     public class ConstantInjectDemo {
     2 
     3         @Inject
     4         @Named("v")
     5         private int v;
     6         public static void main(String[] args) {
     7 
     8             ConstantInjectDemo cid = Guice.createInjector(new Module() {
     9                 @Override
    10                 public void configure(Binder binder) {
    11                     binder.bindConstant().annotatedWith(Names.named("v")).to(12);
    12                 }
    13             }).getInstance(ConstantInjectDemo.class);
    14             System.out.println(cid.v);
    15         }
    16     }
    17 
    18 

    當然,既然可以使用Named,也就可以使用自己寫注解了。但是看起來好像沒有多大作用。除了上述寫法,也可以用下面的方式實現。

    binder.bind(int.class).annotatedWith(Names.named("v")).toInstance(12);

    除了可以綁定int外,在ConstantBindingBuilder類中還可以綁定其它的基本類型。

    com.google.inject.binder.ConstantBindingBuilder.to(String)
    com.google.inject.binder.ConstantBindingBuilder.to(
    long)
    com.google.inject.binder.ConstantBindingBuilder.to(
    boolean)
    com.google.inject.binder.ConstantBindingBuilder.to(
    double)
    com.google.inject.binder.ConstantBindingBuilder.to(
    float)
    com.google.inject.binder.ConstantBindingBuilder.to(
    short)
    com.google.inject.binder.ConstantBindingBuilder.to(
    char)

     

    1.3.4 綁定Properties

    除了可以綁定基本類型外,還可以綁定一個Properties到Guice中,當然了,由于Properties本質上時一個Map<String,String>,因此Guice也允許綁定一個Map<String,String>。


     1     @Inject
     2     @Named("web")
     3     private String web;
     4 
     5     public static void main(String[] args) {
     6 
     7         ConstantInjectDemo cid = Guice.createInjector(new Module() {
     8             @Override
     9             public void configure(Binder binder) {
    10                 Properties properties= new Properties();
    11                 properties.setProperty("web""www.imxylz.cn");
    12                 Names.bindProperties(binder, properties);
    13             }
    14         }).getInstance(ConstantInjectDemo.class);
    15         System.out.println(cid.web);
    16     }
    17 
    18 
     
    上一篇:Google Guice 入門教程02 - 依賴注入(2)
    下一篇:Google Guice 入門教程04 - 依賴注入(4)

    ©2009-2014 IMXYLZ |求賢若渴
    posted on 2009-12-24 19:13 imxylz 閱讀(18668) 評論(1)  編輯  收藏 所屬分類: Google Guice

    評論

    # re: Google Guice 入門教程03 - 依賴注入(3) 2013-11-16 10:56 cyning
    給你提個錯誤吧 第一個MultiInterfaceServiceDemo中的service全部是private 下面的demo對象有訪問權限 這個不對吧 訪問權限應該是public吧  回復  更多評論
      


    ©2009-2014 IMXYLZ
    主站蜘蛛池模板: 国产成人3p视频免费观看| 久久精品国产亚洲av麻豆色欲| 巨胸喷奶水www永久免费| 亚洲成a人片在线观看中文动漫| 台湾一级毛片永久免费| 黄色免费网址在线观看| 亚洲激情在线观看| 日本免费无遮挡吸乳视频电影| 波多野结衣免费一区视频 | 亚洲国产精品久久久久久| 毛片免费vip会员在线看| 三年片免费高清版 | 亚洲av日韩av高潮潮喷无码| 女人张开腿等男人桶免费视频| 精品久久久久久无码免费| 77777亚洲午夜久久多喷| 亚洲国产另类久久久精品黑人| 夭天干天天做天天免费看| 中文字幕无码免费久久| 瑟瑟网站免费网站入口| 亚洲字幕在线观看| 亚洲精品无码永久中文字幕| 日本一道一区二区免费看| 日本免费一区二区在线观看| 亚洲黄片手机免费观看| 亚洲最大的成人网| 精品亚洲麻豆1区2区3区| 国产AV无码专区亚洲AWWW| 在线观着免费观看国产黄| 最近中文字幕无免费| aaa毛片免费观看| 美女免费精品高清毛片在线视| 亚洲国产成人精品激情| 亚洲AV日韩AV永久无码免下载| 亚洲国产精品一区二区九九| 精品久久久久久久免费人妻| 日韩精品免费一级视频| 中文字幕成人免费视频| 国产精品免费无遮挡无码永久视频 | 亚洲成人国产精品| 日韩在线a视频免费播放|