Android RoboGuice使用指南(5):Binding Annotations
3275 点击·0 回帖
![]() | ![]() | |
![]() | 有些情况需要将同一类型映射到不同的类实现,还是使用绘图的例子. IShape, Rectangle, MyRectangle, MySquare,有如下继承关系: ![]() 我们可能需要将IShape 同时映射到MyRectangle 和MySquare ,这时可以使用Binding Annotation 来实现。 这时使用类型和annotation (标注)可以唯一确定一个Binding。Type 和annotation 对称为Key(键)。 为了同时使用MyRectangle和MySequare,我们定义两个annotation,如下 [java] 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 { } 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 { } 定义了两个标注 @Rectangle, @Square, 至于@BindingAnnotation,@Target,@Retention你并不需要详细了解,有兴趣的可以参见java Annotation tutorial . 简单的说明如下: @BindingAnnotation 通知这是一个Binding Annotation,如果将多个个标注应用到同一个元素时,Guice会报错。 @Target({FIELD, PARAMETER, METHOD}) 表示这个标注可以应用到类成员变量,函数的参数或时方法。 @Retention(RUNTIME) 表示这个标注在程序运行时可以使用Reflection读取。 创建一个BindingAnnotationsDemo 用来绘制两个图形: [java] 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); } } 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); } } 使用标注将shape1 绑定到MyRectangle, shape2绑定到MySquare,对应的Module 定义如下: [java] 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); } } ![]() Inject 可以应用到Field (成员变量),Parameter (参数)或Method(方法),前面的例子都是应用到Field上,如果应用到参数可以有如下形式: [java] @Inject public IShape getShape(@Rectangle IShape shape){ ... } @Inject public IShape getShape(@Rectangle IShape shape){ ... } 如果你不想自定义Annotation,可以使用Guice自带的@Name标注来解决同一类型绑定到不同实现的问题。 修改上面代码: [java] //@Inject @Rectangle IShape shape1; //@Inject @Square IShape shape2; @Inject @Named("Rectangle") IShape shape1; @Inject @Named("Square") IShape shape2; //@Inject @Rectangle IShape shape1; //@Inject @Square IShape shape2; @Inject @Named("Rectangle") IShape shape1; @Inject @Named("Square") IShape shape2; 修改绑定如下: [java] view plaincopyprint? //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); //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); 这种方法简单,但编译器无法检测字符串,比如将”Square”错写为”Sqare”,编译器无法查出这个错误,此时到运行时才可能发现 shape2 无法注入,因此建议尽量少用Named. | |
![]() | ![]() |