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
|求賢若渴