xylz,imxylz

          關(guān)注后端架構(gòu)、中間件、分布式和并發(fā)編程

             :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            111 隨筆 :: 10 文章 :: 2680 評(píng)論 :: 0 Trackbacks

          1.2 屬性注入(Field Inject)

          1.2.1 基本屬性注入

          首先來(lái)看一個(gè)例子。Service.java


          1 @ImplementedBy(ServiceImpl.class)
          2 public interface Service {
          3     void execute();
          4 }

          ServiceImpl.java


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

          FieldInjectDemo.java


           1 /** a demo with Field inject
           2  * @author xylz (www.imxylz.cn)
           3  * @version $Rev: 71 $
           4  */
           5 public class FieldInjectDemo {
           6     @Inject
           7     private Service servcie;
           8     public Service getServcie() {
           9         return servcie;
          10     }
          11     public static void main(String[] args) {
          12         FieldInjectDemo demo = Guice.createInjector().getInstance(FieldInjectDemo.class);
          13         demo.getServcie().execute();
          14     }
          15 }

          這個(gè)例子比較簡(jiǎn)單。具體來(lái)說(shuō)就是將接口Service通過(guò)@Inject注解注入到FieldInjectDemo類中,然后再FieldInjectDemo類中使用此服務(wù)而已。當(dāng)然Service服務(wù)已經(jīng)通過(guò)@ImplementedBy注解關(guān)聯(lián)到ServiceImpl 類中,每次生成一個(gè)新的實(shí)例(非單例)。注意,這里FieldInjectDemo類沒(méi)有通過(guò)Module等關(guān)聯(lián)到Guice中,具體可以查看《》。

          意料之中得到了我們期待的結(jié)果。

          同樣,我們通過(guò)問(wèn)答的方式來(lái)加深理解(注意,入門教程我們只是強(qiáng)調(diào)怎么使用,至于原理和底層的思想我們放到高級(jí)教程中再談)。

          問(wèn)題(1):可以自己構(gòu)造FieldInjectDemo 對(duì)象而不通過(guò)Guice么?


           1 /** field inject demo2
           2  * @author xylz (www.imxylz.cn)
           3  * @version $Rev: 73 $
           4  */
           5 public class FieldInjectDemo2 {
           6     @Inject
           7     private Service servcie;
           8     public Service getServcie() {
           9         return servcie;
          10     }
          11     public static void main(String[] args) {
          12         FieldInjectDemo2 fd = new FieldInjectDemo2();
          13         fd.getServcie().execute();
          14     }
          15 }

          就像上面的例子中一樣,然后運(yùn)行下看看?非常不幸,我們得到了一個(gè)誰(shuí)都不喜歡的結(jié)果。


          Exception in thread "main" java.lang.NullPointerException
              at cn.imxylz.study.guice.inject.FieldInjectDemo2.main(FieldInjectDemo2.java:
          22)

          很顯然,由于FieldInjectDemo2不屬于Guice容器(暫且稱為容器吧)托管,這樣Service服務(wù)沒(méi)有機(jī)會(huì)被注入到FieldInjectDemo2類中。

          問(wèn)題(2):可以注入靜態(tài)屬性么?

          看下面的代碼。


           1 public class FieldInjectDemo2 {
           2     @Inject
           3     private static Service servcie;
           4     public static Service getServcie() {
           5         return servcie;
           6     }
           7     public static void main(String[] args) {
           8         FieldInjectDemo2 fd = Guice.createInjector().getInstance(FieldInjectDemo2.class);
           9         FieldInjectDemo2.getServcie().execute();
          10     }
          11 }

          很不幸!運(yùn)行結(jié)果告訴我們Guice看起來(lái)還不支持靜態(tài)字段注入。

          好了,上面兩個(gè)問(wèn)題我們暫且放下,我們繼續(xù)學(xué)習(xí)其它注入功能。

          1.2.2 構(gòu)造函數(shù)注入(Constructor Inject)

          繼續(xù)看例子。例子是說(shuō)明問(wèn)題的很好方式。


           1     /**
           2      * $Id: ConstructorInjectDemo.java 75 2009-12-23 14:22:35Z xylz $
           3      * xylz study project (www.imxylz.cn)
           4      */
           5     package cn.imxylz.study.guice.inject;
           6 
           7     import com.google.inject.Guice;
           8     import com.google.inject.Inject;
           9 
          10     /** a demo with constructor inject
          11      * @author xylz (www.imxylz.cn)
          12      * @version $Rev: 75 $
          13      */
          14     public class ConstructorInjectDemo {
          15 
          16         private Service service;
          17         @Inject
          18         public ConstructorInjectDemo(Service service) {
          19             this.service=service;
          20         }
          21         public Service getService() {
          22             return service;
          23         }
          24         public static void main(String[] args) {
          25             ConstructorInjectDemo cid = Guice.createInjector().getInstance(ConstructorInjectDemo.class);
          26             cid.getService().execute();
          27         }
          28 
          29     }
          30 
          31 

          我們?cè)跇?gòu)造函數(shù)上添加@Inject來(lái)達(dá)到自動(dòng)注入的目的。構(gòu)造函數(shù)注入的好處是可以保證只有一個(gè)地方來(lái)完成屬性注入,這樣可以確保在構(gòu)造函數(shù)中完成一些初始化工作(盡管不推薦這么做)。當(dāng)然構(gòu)造函數(shù)注入的缺點(diǎn)是類的實(shí)例化與參數(shù)綁定了,限制了實(shí)例化類的方式。

          問(wèn)題(3):構(gòu)造函數(shù)中可以自動(dòng)注入多個(gè)參數(shù)么?


           1     public class ConstructorInjectDemo {
           2 
           3         private Service service;
           4         private HelloWorld helloWorld;
           5         @Inject
           6         public ConstructorInjectDemo(Service service,HelloWorld helloWorld) {
           7             this.service=service;
           8             this.helloWorld=helloWorld;
           9         }
          10         public Service getService() {
          11             return service;
          12         }
          13         public HelloWorld getHelloWorld() {
          14             return helloWorld;
          15         }
          16         public static void main(String[] args) {
          17             ConstructorInjectDemo cid = Guice.createInjector().getInstance(ConstructorInjectDemo.class);
          18             cid.getService().execute();
          19             System.out.println(cid.getHelloWorld().sayHello());
          20         }
          21     }
          22 
          23 

          非常完美的支持了多參數(shù)構(gòu)造函數(shù)注入。當(dāng)然了沒(méi)有必要寫多個(gè)@Inject,而且寫了的話不能通過(guò)編譯。

          1.2.3 Setter注入(Setter Method Inject)

          有了上面的基礎(chǔ)我們?cè)賮?lái)看Setter注入就非常簡(jiǎn)單了,只不過(guò)在setter方法上增加一個(gè)@Inject注解而已。


           1     public class SetterInjectDemo {
           2 
           3         private Service service;
           4 
           5         @Inject
           6         public void setService(Service service) {
           7             this.service = service;
           8         }
           9 
          10         public Service getService() {
          11             return service;
          12         }
          13 
          14         public static void main(String[] args) {
          15             SetterInjectDemo sid = Guice.createInjector().getInstance(SetterInjectDemo.class);
          16             sid.getService().execute();
          17         }
          18 
          19     }
          20 
          21 

          好了我們?cè)倩仡^看問(wèn)題2的靜態(tài)注入(static inject)。下面的例子演示了如何注入一個(gè)靜態(tài)的字段。


           1     /** a demo for static field inject
           2      * @author xylz (www.imxylz.cn)
           3      * @version $Rev: 78 $
           4      */
           5     public class StaticFieldInjectDemo {
           6 
           7         @Inject
           8         private static Service service;
           9 
          10         public static void main(String[] args) {
          11             Guice.createInjector(new Module() {
          12                 @Override
          13                 public void configure(Binder binder) {
          14                     binder.requestStaticInjection(StaticFieldInjectDemo.class);
          15                 }
          16             });
          17             StaticFieldInjectDemo.service.execute();
          18         }
          19     }
          20 
          21 

          非常棒!上面我們并沒(méi)有使用Guice獲取一個(gè)StaticFieldInjectDemo實(shí)例(廢話),實(shí)際上static字段(屬性)是類相關(guān)的,因此我們需要請(qǐng)求靜態(tài)注入服務(wù)。但是一個(gè)好處是在外面看起來(lái)我們的服務(wù)沒(méi)有Guice綁定,甚至client不知道(或者不關(guān)心)服務(wù)的注入過(guò)程。

          再回到問(wèn)題(1),參考上面靜態(tài)注入的過(guò)程,我們可以使用下面的方式來(lái)注入實(shí)例變量的屬性。


           1     public class InstanceFieldInjectDemo {
           2 
           3         @Inject
           4         private Service service;
           5         public static void main(String[] args) {
           6            final InstanceFieldInjectDemo ifid = new InstanceFieldInjectDemo();
           7             Guice.createInjector(new Module() {
           8                 @Override
           9                 public void configure(Binder binder) {
          10                     binder.requestInjection(ifid);
          11                 }
          12             });
          13             ifid.service.execute();
          14         }
          15     }
          16 
          17 

          實(shí)際上這里有一種簡(jiǎn)便的方法來(lái)注入字段,實(shí)際上此方法也支持Setter注入。


           1     public class InstanceFieldInjectDemo {
           2 
           3         @Inject
           4         private Service service;
           5         public static void main(String[] args) {
           6             InstanceFieldInjectDemo ifid = new InstanceFieldInjectDemo();
           7             Guice.createInjector().injectMembers(ifid);
           8             ifid.service.execute();
           9         }
          10     }
          11 
          12 

          好了既然是入門教程,我們就不討論更深層次的東西了。

          上一篇:Google Guice 入門教程01 - 依賴注入(1)

          下一篇:Google Guice 入門教程03 - 依賴注入(3)



          ©2009-2014 IMXYLZ |求賢若渴
          posted on 2009-12-23 23:45 imxylz 閱讀(20474) 評(píng)論(3)  編輯  收藏 所屬分類: Google Guice

          評(píng)論

          # re: Google Guice 入門教程02 - 依賴注入(2) 2013-05-22 17:07 Teaey
          在使用中發(fā)現(xiàn)兩個(gè)問(wèn)題,想請(qǐng)教下:
          1. 通過(guò)Provider new出來(lái)的對(duì)象是不會(huì)自動(dòng)注入Injdect的實(shí)例域的
          2. Provider方式@Singleton注解失效,只有手動(dòng)調(diào)用in(Scopes.SINGLETON);來(lái)綁定單例  回復(fù)  更多評(píng)論
            

          # re: Google Guice 入門教程02 - 依賴注入(2) 2015-03-10 18:08 庫(kù)特
          我發(fā)現(xiàn)setter注入的時(shí)候,
          @Inject
          public void setHello2(Hello2 hello2, Hello3 hello3) {
          this.hello2 = hello2;
          this.hello3 = hello3;
          }
          或者
          @Inject
          public void setHello3(Hello3 hello3, Hello2 hello2) {
          this.hello2 = hello2;
          this.hello3 = hello3;
          }
          也是可以的,多setter注(好)入(假)  回復(fù)  更多評(píng)論
            


          ©2009-2014 IMXYLZ
          主站蜘蛛池模板: 宽甸| 毕节市| 通榆县| 阳西县| 台中县| 鲜城| 台前县| 嘉祥县| 渭南市| 长治县| 海阳市| 仲巴县| 铜山县| 太湖县| 绥滨县| 林甸县| 天津市| 晋州市| 罗平县| 和平县| 兴业县| 德江县| 峡江县| 长岭县| 武乡县| 永德县| 周宁县| 黔南| 曲麻莱县| 丽江市| 高唐县| 体育| 泌阳县| 黄浦区| 深圳市| 杨浦区| 社旗县| 平安县| 大洼县| 宜兴市| 中阳县|