有些情況需要將同一類型映射到不同的類實(shí)現(xiàn),還是使用繪圖的例子.
IShape, Rectangle, MyRectangle, MySquare, 有如下繼承關(guān)系:
http://wiki.jikexueyuan.com/project/android-roboguice/images/8.png" alt="" />
我們可能需要將 IShape 同時(shí)映射到 MyRectangle 和 MySquare ,這時(shí)可以使用 Binding Annotation 來(lái)實(shí)現(xiàn)。 這時(shí)使用類型和 annotation (標(biāo)注)可以唯一確定一個(gè) Binding。Type 和 annotation 對(duì)稱為 Key(鍵)。
為了同時(shí)使用 MyRectangle 和 MySequare,我們定義兩個(gè) annotation,如下
import com.google.inject.BindingAnnotation;
import java.lang.annotation.Target;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
...
@BindingAnnotation
@Target({ FIELD, PARAMETER, METHOD })
@Retention(RUNTIME)
public @interface Rectangle {
}
...
@BindingAnnotation
@Target({ FIELD, PARAMETER, METHOD })
@Retention(RUNTIME)
public @interface Square {
}
定義了兩個(gè)標(biāo)注 @Rectangle, @Square, 至于 @BindingAnnotation,@Target,@Retention 你并不需要詳細(xì)了解,有興趣的可以參見 Java Annotation tutorial
簡(jiǎn)單的說(shuō)明如下:
創(chuàng)建一個(gè) BindingAnnotationsDemo 用來(lái)繪制兩個(gè)圖形:
public class BindingAnnotationsDemo extends Graphics2DActivity{
@Inject @Rectangle IShape shape1;
@Inject @Square IShape shape2;
protected void drawImage(){
/**
* The semi-opaque blue color in
* the ARGB space (alpha is 0x78)
*/
Color blueColor = new Color(0x780000ff,true);
/**
* The semi-opaque green color in the ARGB space (alpha is 0x78)
*/
Color greenColor = new Color(0x7800ff00,true);
graphics2D.clear(Color.WHITE);
graphics2D.Reset();
SolidBrush brush=new SolidBrush(blueColor);
graphics2D.fill(brush,shape1);
AffineTransform at = new AffineTransform();
at.translate(20, 20);
graphics2D.setAffineTransform(at);
brush=new SolidBrush(greenColor);
graphics2D.fill(brush,shape2);
}
}
使用標(biāo)注將 shape1 綁定到 MyRectangle, shape2 綁定到 MySquare,對(duì)應(yīng)的 Module 定義如下:
public class Graphics2DModule extends AbstractAndroidModule{
@Override
protected void configure() {
bind(IShape.class)
.annotatedWith(Rectangle.class)
.to(MyRectangle.class);
bind(IShape.class)
.annotatedWith(Square.class)
.to(MySquare.class);
}
}
http://wiki.jikexueyuan.com/project/android-roboguice/images/9.png" alt="" />
Inject 可以應(yīng)用到 Field (成員變量),Parameter (參數(shù))或 Method (方法),前面的例子都是應(yīng)用到 Field 上,如果應(yīng)用到參數(shù)可以有如下形式:
@Inject
public IShape getShape(@Rectangle IShape shape){
...
}
如果你不想自定義 Annotation,可以使用 Guice 自帶的 @Name 標(biāo)注來(lái)解決同一類型綁定到不同實(shí)現(xiàn)的問(wèn)題。
修改上面代碼:
//@Inject @Rectangle IShape shape1;
//@Inject @Square IShape shape2;
@Inject @Named("Rectangle") IShape shape1;
@Inject @Named("Square") IShape shape2;
修改綁定如下:
//bind(IShape.class)
//.annotatedWith(Rectangle.class)
//.to(MyRectangle.class);
//bind(IShape.class)
//.annotatedWith(Square.class)
//.to(MySquare.class);
bind(IShape.class)
.annotatedWith(Names.named("Rectangle"))
.to(MyRectangle.class);
bind(IShape.class)
.annotatedWith(Names.named("Square"))
.to(MySquare.class);
這種方法簡(jiǎn)單,但編譯器無(wú)法檢測(cè)字符串,比如將 ”Square” 錯(cuò)寫為 ”Sqare”,編譯器無(wú)法查出這個(gè)錯(cuò)誤,此時(shí)到運(yùn)行時(shí)才可能發(fā)現(xiàn) shape2 無(wú)法注入,因此建議盡量少用 Named.