Guice笔记

<p>1、Hello World!</p>
<p><textarea cols="66" rows="38" name="code" class="java:collapse">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();
}
}</textarea></p>
<p></p>
<p>2、单例问题</p>
<p></p>
<p>在测试类中直接拿Service对象比较</p>
<p></p>
<p><textarea cols="71" rows="15" name="code" class="java">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{
...
}</textarea></p>
<p></p>
<p>3、返回的是正常的实例,未做转换和代理。</p>
<p></p>
<p><textarea cols="50" rows="15" name="code" class="java">Service service = inj.getInstance(Service.class);
System.out.println(service.getClass().getName());
//输出Service,是正常的实例,未做转换和代理。</textarea></p>
<p></p>
<p></p>
<p>4、无法绑定多个实现到一个借口</p>
<p></p>
<p><textarea cols="61" rows="15" name="code" class="c-sharp">再建一个实现类
public class ServiceImplAgain implements Service{
...
}
然后修改Module类
...
binder.bind(Service.class).to(ServiceImpl.class);
binder.bind(Service.class).to(ServiceImplAgain.class);
..
//系统报错</textarea></p>
<p></p>
<p>5、不可以自己绑定自己,但可以绑定子类到自己,也可以绑定到自己构造出来的实例上。</p>
<p></p>
<p><textarea cols="68" rows="18" name="code" class="c-sharp">...
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());
...
//绑定到实例上
</textarea></p>
<p></p>
<p></p>
<p>5、可以Guice提供一个方式(Provider<T>),允许自己提供构造对象的方式。</p>
<p><textarea cols="79" rows="15" name="code" class="c-sharp">//方法一
...
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出来都是新对象
}
}
</textarea></p>
<p></p>
<p></p>
<p>6、可以直接获取实例而不通过Modue绑定。</p>
<p><textarea cols="50" rows="15" name="code" class="java:nocontrols">Injector inj= Guice.createInjector();
Service service = inj.getInstance(ServiceImpl.class);
System.out.println(service.sayHello());</textarea></p>
<p></p>
<p></p>
<p>7、使用注解实现注入,等于是默认实现类。</p>
<p></p>
<p><textarea cols="50" rows="15" name="code" class="java">@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</textarea></p>
<p></p>
<p>8、静态属性注入</p>
<p></p>
<p><textarea cols="52" rows="15" name="code" class="java">@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():
}
}</textarea></p>
<p></p>
<p>9、构造函数注入可以自动注入多个参数</p>
<p></p>
<p><textarea cols="50" rows="15" name="code" class="java">...
@Inject
public Client(Service service,Service2 service2){
this.service = service;
this.service2 = service2;
}
...</textarea></p>
<p></p>
<p>10、使用setter注入</p>
<p></p>
<p><textarea cols="50" rows="15" name="code" class="java">...
@Inject
public void setService(Service service){
this.service = service;
}
...</textarea></p>
<p></p>
<p></p>
<p>11、注入实例变量的属性</p>
<p></p>
<p><textarea cols="57" rows="15" name="code" class="java">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);//一句搞定
...</textarea></p>
<p></p>
<p></p>
<p>12、绑定多个服务</p>
<p></p>
<p><textarea cols="83" rows="15" name="code" class="c-sharp">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();
}
}
</textarea></p>
<p></p>
<p>静态注入 多个服务</p>
<p></p>
<p><textarea cols="83" rows="15" name="code" class="java">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();
}
}</textarea></p>
<p></p>
<p>太懒,不想写注解怎么办,用Names模板</p>
<p></p>
<p><textarea cols="91" rows="15" name="code" class="java">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();
}
}</textarea></p>
<p></p>
<p></p>
<p>13、绑定常量</p>
<p><textarea cols="78" rows="15" name="code" class="java">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);
}
}
</textarea></p>
<p></p>
<p></p>
<p>14、绑定Properties</p>
<p><textarea cols="79" rows="15" name="code" class="java">@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);
}
</textarea></p>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值