热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

GoogleGuice注入(@Inject注解)

最详细解析:GoogleGuice小试牛刀(@Inject注解)GoogleGuice之AOP(面向切面编程)比较全面文档:http:blog.csdn.netzhaowen25arti

最详细解析:Google Guice 小试牛刀(@Inject注解)

Google Guice之AOP(面向切面编程)

比较全面文档:http://blog.csdn.net/zhaowen25/article/details/52927193

下面的是一些入口

上一节介绍通过注解来实现绑定关系,这一节介绍如何通过@Inject来完成依赖注入的功能:

(1)属性注入

(2)构造方法注入

(3)setter方法注入

一.属性注入

(1)创建一个接口Hello.Java和一个实现类HelloImpl

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. package guice.di;  
  2.   
  3. import com.google.inject.ImplementedBy;  
  4. //将这个接口和实现类HelloImpl绑定到一起  
  5. @ImplementedBy(HelloImpl.class)  
  6. public interface Hello {  
  7.     void sayHello() ;  
  8. }  
  9.   
  10.   
  11. package guice.di;  
  12.   
  13. //这里没有加@Singleton,表示是动态创建这个类,不是单例的  
  14. public class HelloImpl implements Hello{  
  15.       
  16.     @Override  
  17.     public void sayHello() {  
  18.         System.out.println("HelloImpl Say Hello");  
  19.     }  
  20. }  

通过@ImplementedBy注解,将接口和实现类绑定在一起


(2)创建一个HelloCaller(包含一个Hello属性)

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. package guice.di;  
  2.   
  3. import com.google.inject.Inject;  
  4.   
  5. //HelloCaller将会去调用Hello这个接口提供的服务  
  6. public class HelloCaller {  
  7.       
  8.     //通过@Inject,来完成属性的注入  
  9.     @Inject  
  10.     private Hello hello ;    //这个就相当于:private Hello hello = new HelloImpl(); 把Hello实例化了
  11.     //调用Hello的sayHello方法(实际上就是去调用HelloImpl的sayHello,因为我们将Hello的实现指定是HelloImpl)  
  12.     public void sayHello(){  
  13.         hello.sayHello() ;  
  14.     }  
  15. }  
通过@Inject注解将Hello属性的实例注入进来


(3)创建一个测试类Client

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. package guice.di;  
  2.   
  3. import com.google.inject.Binder;  
  4. import com.google.inject.Guice;  
  5. import com.google.inject.Injector;  
  6. import com.google.inject.Module;  
  7.   
  8. public class Client {  
  9.       
  10.     //创建一个测试程序  
  11.     public static void main(String[] args) {  
  12.           
  13.         Injector in = Guice.createInjector(new Module(){  
  14.             @Override  
  15.             public void configure(Binder arg0) {  
  16.                 //什么也不写  
  17.             }  
  18.         }) ;  
  19.         //得到HelloCaller的实例  
  20.         HelloCaller helloCaller = in.getInstance(HelloCaller.class) ;  
  21.         //调用sayHello方法  
  22.         helloCaller.sayHello() ;  
  23.     }  
  24.       
  25. }  

结果:

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. HelloImpl Say Hello  


二. 构造方法注入

(1)Hello和HelloImpl类还是上面那样不用变,唯一变化的是HelloCaller类

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. package guice.di;  
  2.   
  3. import com.google.inject.Inject;  
  4.   
  5. public class HelloCaller1 {  
  6.     //包含一个Hello属性  
  7.     private Hello hello ;  
  8.     //@Inject注解写在构造方法上,通过构造方法的方式注入属性hello  
  9.     @Inject  
  10.     public HelloCaller1(Hello hello){  
  11.         this.hello = hello ;  
  12.     }  
  13.       
  14.     public void sayHello(){  
  15.         hello.sayHello() ;  
  16.     }  
  17. }  

(2)创建测试程序

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. package guice.di;  
  2.   
  3. import com.google.inject.Binder;  
  4. import com.google.inject.Guice;  
  5. import com.google.inject.Injector;  
  6. import com.google.inject.Module;  
  7.   
  8. public class Client {  
  9.       
  10.     //创建一个测试程序  
  11.     public static void main(String[] args) {  
  12.           
  13.         Injector in = Guice.createInjector(new Module(){  
  14.             @Override  
  15.             public void configure(Binder arg0) {  
  16.                 //什么也不写  
  17.             }  
  18.         }) ;  
  19.         //得到HelloCaller的实例  
  20.         HelloCaller1 helloCaller = in.getInstance(HelloCaller1.class) ;  
  21.         //调用sayHello方法  
  22.         helloCaller.sayHello() ;  
  23.           
  24.     }  
  25.       
  26. }  

结果:

HelloImpl Say Hello

三,setter方式注入

(1)Hello和HelloImpl类还是上面那样不用变,唯一变化的是HelloCaller类

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. "font-size:14px;">package guice.di;  
  2.   
  3.   
  4. import com.google.inject.Inject;  
  5.   
  6.   
  7. public class HelloCaller2 {  
  8. "white-space:pre">    
  9. "white-space:pre">  private Hello hello ;  
  10.   
  11.   
  12. "white-space:pre">  public Hello getHello() {  
  13. "white-space:pre">      return hello;  
  14. "white-space:pre">  }  
  15. "white-space:pre">  //通过setter方法来注入hello属性  
  16. "white-space:pre">  @Inject  
  17. "white-space:pre">  public void setHello(Hello hello) {  
  18. "white-space:pre">      this.hello = hello;  
  19. "white-space:pre">  }  
  20. "white-space:pre">    
  21. }  

(2)创建测试程序

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. "font-size:14px;">package guice.di;  
  2.   
  3. import com.google.inject.Binder;  
  4. import com.google.inject.Guice;  
  5. import com.google.inject.Injector;  
  6. import com.google.inject.Module;  
  7.   
  8. public class Client {  
  9.       
  10.     //创建一个测试程序  
  11.     public static void main(String[] args) {  
  12.           
  13.         Injector in = Guice.createInjector(new Module(){  
  14.             @Override  
  15.             public void configure(Binder arg0) {  
  16.                 //什么也不写  
  17.             }  
  18.         }) ;  
  19.         //得到HelloCaller的实例  
  20.         HelloCaller1 helloCaller = in.getInstance(HelloCaller1.class) ;  
  21.         //调用sayHello方法  
  22.         helloCaller.sayHello() ;  
  23.           
  24.     }  
  25.       
  26. }  

结果:

HelloImpl Say Hello


上面介绍了Guice框架的三种注入方式:属性注入,构造方法注入,setter方法注入


最最重要的是,在自己的netty后台服务项目中,启动netty服务的时候startup方法可以将Injector对象传入到WebContainer类中,然后在Registerxx中,注册User类为web接口时,将Injector对象放入对应的User类中,在Registerxx注册服务时实例化User类的时候,就将User中的Injector属性赋值。然后在User类中就可以使用Injector中的对象。

其实和Spring差不多,只是一个是用xml的,一个使用注解的。

特别关注:

  1.   Injector in = Guice.createInjector(new Module(){  
  2.             @Override  
  3.             public void configure(Binder arg0) {  
  4.                 //什么也不写  
  5.             }  
  6.         }) ;  

思想提升

Guice 希望在不牺牲可维护性的情况下去除所有这些程式化的代码。

使用 Guice,你只需要实现模块类。Guice 将一个绑定器传入你的模块,你的模块使 用绑定器来连接接口和实现。以下模块代码告诉 Guice 将 Service映射到单件模式的 ServiceImpl:

public class MyModule implements Module {
  public void configure(Binder binder) {
   binder.bind(Service.class)
    .to(ServiceImpl.class)
    .in(Scopes.SINGLETON);
  }
}

模块类告诉 Guice 我们想注入什么东西。那么,我们该如何告诉 Guice 我们想把它 注入到哪里呢?使用 Guice,你可以使用 @Inject 标注你的构造器,方法或字段:

public class Client {
  private final Service service;
  @Inject
  public Client(Service service) {
   this.service = service;
  }
  public void go() {
   service.go();
  }
}

@Inject 标注可以清楚地告诉其他程序员你的类中哪些成员是被注入的。

为了让 Guice向 Client 中注入,我们必须直接让 Guice 帮我们创建Client 的实例 ,或者,其他类必须包含被注入的Client 实例。

将对象A注入到对象B中用@inject

而获取对象时:可以直接使用

Test test = injector.getInstance(Test.class);
System.out.println(test.getA());
test.setA("SFFFFFFFFFFFFFF");
System.out.println(test.getA());
不管Test.Class是不是impl还是interface。甚至是与Guice没有任何关系的类,我们都可以获得:

Test test = injector.getInstance(Test.class);
就相当于:

Test test = new Test();
如果Test类中有Inject注解,那么再将注解的对象注入test实体类中。还有一点需要注意

Test test1 = injector.getInstance(Test.class);
Test test2 = injector.getInstance(Test.class);

test1和test2是同一个对象,同一个路径的。而下面的代码只是实现注解对象的绑定,从一个接口类绑定到实体类。没有其他别的含义

 binder.bind(Service.class)
    .to(ServiceImpl.class)


   

推荐阅读
author-avatar
绝望的贵族_500
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有