Google Guice笔记

1、Hello World!

1、定义Service  
Service.java  
  
public interface Service{  
  public void sayHello();  
}  
2、定义实现类  
ServiceImpl.java  
  
public class ServiceImpl implements Service{  
  @Override  
  public String sayHello() {  
    return "Hello World!";     
  }  
}  
3、客户端  
Client.java  
public class Client {  
  //@Inject 也可以再这里注入  
  public Service service;  
  /*这里是在构造函数中注入了 
    优点是可以再构造函数中完成一些初始化工作 
     缺点是类的实例化与参数绑定,限制了实例化类的方式 
  */  
  @Inject  
  public Client(Service service){  
    this.service = service;  
  }  
  public void print(){  
   System.out.println(service.say());  
  }  
}  
4、测试类  
public class Test extends TestCase{  
  public void testGuice(){  
    Injector inj = Guice.createInjector(new Module(){  
      @Override  
      public void configure(Binder binder){  
        binder.bind(Service.class).to(ServiceImpl.class);  
      }  
    });  
    Client client = inj.getInstance(Client.class);  
    client.print();  
  }  
}  

2、单例问题

在测试类中直接拿Service对象比较

Service service = inj.getInstance(Service.class);  
Service service2 =inj.getInstance(Service.class);  
Assert.assertEquals(service.hashCode(),service2.hashCode());  
//不等,每次都会返回一个新的实例  
  
修改代码Module中的方法  
...  
binder.bind(Service.class).to(Serviceimpl.class).in(Scopes.SINGLETON);  
...  
//再次测试  
Service service = inj.getInstance(Service.class);  
Service service2 =inj.getInstance(Service.class);  
Assert.assertEquals(service.hashCode(),service2.hashCode());  
//相等,返回是同一个实例  
  
//--------------------我是分割线 -----------------------------  
//也可以通过在实现类上添加@Singleton标注来完成,  
@Singleton  
public class ServiceImpl implements Service{  
  ...  
}  

3、返回的是正常的实例,未做转换和代理。

Service service = inj.getInstance(Service.class);  
System.out.println(service.getClass().getName());  
//输出Service,是正常的实例,未做转换和代理。  

4、无法绑定多个实现到一个接口

再建一个实现类  
public class ServiceImplAgain implements Service{  
  ...  
}  
然后修改Module类  
...  
binder.bind(Service.class).to(ServiceImpl.class);  
binder.bind(Service.class).to(ServiceImplAgain.class);  
..  
//系统报错  

5、不可以自己绑定自己,但可以绑定子类到自己,也可以绑定到自己构造出来的实例上。

...  
binder.bind(ServiceImpl.class).to(ServiceImpl.class);  
...  
//报错 ,不可以自己绑定自己 Binding porins to itserlf  
  
//--------------------我是分割线---------------------------  
  
public class ServiceSubImpl extends ServiceImpl{  
  ...  
}  
...  
binder.bind(ServiceImpl.class).to(ServiceSubImpl.class);  
...  
/*运行正常,支持子类绑定,这样即使我们将一个实现类发布出去(尽管不推荐这么做),我们再后期仍然有拌饭替换实现类。*/  
  
//--------------------我是分割线---------------------------  
...  
binder.bind(Service.class).to(new ServiceImpl());  
...  
//绑定到实例上  

5、可以Guice提供一个方式(Provider<T>),允许自己提供构造对象的方式。

//方法一  
...  
binder.bind(Service.class).toProvider(new Provider<Service>() {  
  @Override  
  public Service get() {  
    return new ServiceImpl();  
  }  
});  
...  
//方法二,或者直接编写类  
public class ServiceProvider implements Provider<Service>{  
  @Override  
  public Service get(){  
    return new ServiceImpl();  
  }  
}  
//正常调用  
...  
binder.bind(Service.class).toProvider(ServiceProvider.class)  
...  
//方法三,也可以再借口上预定义  
@ProvideBy(ServiceProvider.class)  
public interface Service{  
  ...  
}  
...  
Service service = Guice.createInjector().getInstance(Client.class)  
...  
//方法四,当然也可以注入Provider,通过Guice获取后,调用get()获取Service的实例  
public class ProviderServiceDemo {  
  @Inject  
  private Provider<Service> provider;  
  
  public static void main(String[] args) {  
    ProviderServiceDemo psd = Guice.createInjector(new Module() {  
      @Override  
      public void configure(Binder binder) {  
        binder.bind(Service.class).toProvider(WwwServiceProvider.class);  
      }}).getInstance(ProviderServiceDemo.class);  
    psd.provider.get().execute();//我们每次get出来都是新对象  
  }  
}  

6、可以直接获取实例而不通过Modue绑定。

Injector inj=  Guice.createInjector();  
Service service = inj.getInstance(ServiceImpl.class);  
System.out.println(service.sayHello());  

7、使用注解实现注入,等于是默认实现类。

@ImplementedBy(ServiceImpl.class)  
public interface Service{  
  String sayHello();  
}  
  
Injector inj = Guice.createInjector();  
Service service = inj.getInstance(Service.class);  
System.out.println(service.sayHello());  
//使用Module关联 优先于 @ImplementedBy  

8、静态属性注入

@Inject  
public Service service;  
//运行正常  
  
@Inject   
public static Service service;  
//如果是刚才的客户端代码,使用时报空指针异常。  
  
//要这么写  
public class Demo{  
  @Inject  
  private static Service service;  
  public static void main(String[] args){  
    Guice.createInjector(new Module(){  
      @Override  
      public void configure(Binder binder){  
        binder.requestStaticInjection(Demo.class);  
      }//这里请求了静态注入服务。  
    });  
    Demo.service.sayHello():  
  }  
}  

9、构造函数注入可以自动注入多个参数

...  
@Inject  
public Client(Service service,Service2 service2){  
  this.service = service;  
  this.service2 = service2;  
}  
...  

10、使用setter注入

...  
@Inject  
public void setService(Service service){  
  this.service = service;  
}  
...  

11、注入实例变量的属性

public class Demo{  
  @Inject  
  private Service service;  
  public static void main(String[] args){  
    final Demo demo = new Demo();  
    Guice.createInjector(new Module(){  
      @Override  
      public void configure(Binder binder){  
        binder.requestInjection(demo);//想实例变量注入属性  
      }  
    });  
    demo.service.sayHello();  
  }  
}  
//更简便的方法  
...  
Guice.createInjector().injectMember(demo);//一句搞定  
...  

12、绑定多个服务

public interface Service{  
  void execute();  
}  
  
public class HomeService implements Service{  
  @Override  
  public void execute(){  
    System.out.println("home");  
  }  
}  
  
public class WwwService implements Service{  
  @Override  
  public void execute(){  
    System.out.println("www");  
  }  
}  
//这里需要定义2个注解  
@Retention(RetentionPolicy.RUNTIME)  
@Target({FIELD,PARAMETER})  
@BindingAnnotation  
public @interface Home {  
}  
  
@Retention(RetentionPolicy.RUNTIME)  
@Target({FIELD,PARAMETER})  
@BindingAnnotation  
public @interface Www {  
}  
  
public class Demo {  
  
  @Inject  
  @Www  
  private Service wwwService;  
  
  @Inject  
  @Home  
  private Service homeService;  
  
  public static void main(String[] args) {  
    Demo demo = Guice.createInjector(new Module() {  
      @Override  
      public void configure(Binder binder) {  
        binder.bind(Service.class).annotatedWith(Www.class).to(WwwService.class);  
        binder.bind(Service.class).annotatedWith(Home.class).to(HomeService.class);  
      }  
      }).getInstance(Demo.class);  
    demo.homeService.execute();  
    demo.wwwService.execute();  
}  
}  

静态注入 多个服务

public class StaticMultiInterfaceServiceDemo {  
  @Inject  
  @Www  
  private static Service wwwService;  
  
  @Inject  
  @Home  
  private static Service homeService;  
  
  public static void main(String[] args) {  
    Guice.createInjector(new Module() {  
      @Override  
      public void configure(Binder binder) {  
        binder.bind(Service.class).annotatedWith(Www.class).to(WwwService.class);  
        binder.bind(Service.class).annotatedWith(Home.class).to(HomeService.class);  
        binder.requestStaticInjection(StaticMultiInterfaceServiceDemo.class);  
      }  
    });  
  StaticMultiInterfaceServiceDemo.homeService.execute();  
  StaticMultiInterfaceServiceDemo.wwwService.execute();  
  }  
}  

太懒,不想写注解怎么办,用Names模板

public class NoAnnotationMultiInterfaceServiceDemo {  
  @Inject  
  @Named("Www")  
  private static Service wwwService;  
  
  @Inject  
  @Named("Home")  
  private static Service homeService;  
  
  public static void main(String[] args) {  
    Guice.createInjector(new Module() {  
      @Override  
      public void configure(Binder binder) {  
        binder.bind(Service.class).annotatedWith(Names.named("Www")).to(WwwService.class);  
        binder.bind(Service.class).annotatedWith(Names.named("Home")).to(HomeService.class);  
        binder.requestStaticInjection(NoAnnotationMultiInterfaceServiceDemo.class);  
      }  
    });  
    NoAnnotationMultiInterfaceServiceDemo.homeService.execute();  
    NoAnnotationMultiInterfaceServiceDemo.wwwService.execute();  
  }  
}  

13、绑定常量

public class ConstantInjectDemo {  
    
  @Inject  
  @Named("v")  
  private int v;  
  public static void main(String[] args) {  
    ConstantInjectDemo cid = Guice.createInjector(new Module() {  
      @Override  
      public void configure(Binder binder) {  
        binder.bindConstant().annotatedWith(Names.named("v")).to(12);  
        //以下方法同样适用(其他基本类型全部适用)  
        //binder.bind(int.class).annotatedWith(Names.named("v")).toInstance(12);  
  
  
      }  
      }).getInstance(ConstantInjectDemo.class);  
    System.out.println(cid.v);  
  }  
}  

14、绑定Properties

@Inject  
@Named("web")  
private String web;  
  
public static void main(String[] args) {  
  ConstantInjectDemo cid = Guice.createInjector(new Module() {  
    @Override  
    public void configure(Binder binder) {  
      Properties properties= new Properties();  
      properties.setProperty("web", "www.imxylz.cn");  
      Names.bindProperties(binder, properties);  
    }  
  }).getInstance(ConstantInjectDemo.class);  
  System.out.println(cid.web);  
}  

转载自:https://blog.csdn.net/escaflone/article/details/5694108

猜你喜欢

转载自blog.csdn.net/huanghanqian/article/details/81077711