Guice学习笔记(二) 常用基本知识

启动和运行
  1. 首先创建你的模块类实例,并将其传入 Guice.createInjector().
  2. Guice 创建一个绑定器 Binder 并将其传入你的模块。
  3. 你的模块使用绑定器来定义绑定。
  4. 基于你所定义的绑定,Guice 创建一个注入器 Injector 并将其返回给你。
  5. 你使用注入器来注入对象。
何为模块
  1. public class MyModule implements Module {
  2.     public void configure(Binder binder) {
  3.         binder.bind(IMyService.class)
  4.           .to(MyServiceImp.class)
  5.           .in(Scopes.SINGLETON);
  6.     }
  7. }

然后实际运用中
  1.         MyApp app = new MyApp();
  2.         Module module = new MyModule();
  3.         Injector in = Guice.createInjector(module);
  4.         in.injectMembers(app);


这样就完成了一次注入

Module里的configure方法是必须实现的 所有的绑定都是在这里定义的 怎么绑定都是可以自己diy的

Guice 的启动有两种模式
一是开发阶段模式
一是产品阶段模式
在开发阶段,Guice 会 根据需要加载单件对象。这样,你的应用 程序可以快速启动,只加载你正在测试的部分。
在产品阶段,Guice 会在启动时加载全部单件对象。这帮助你尽早捕获错误,提前优化性能。

使用方法
createInjector(Stage stage, Module... modules)

'     stage可以使用
Stage.DEVELOPMENT和Stage.PRODUCTION
后者将会在初始化的时期就早期进行注入
前者在用到时方会进行注入




  1. public class MyModule implements Module {
  2.   public void configure(Binder binder) {
  3.     // Bind Foo to FooImpl. Guice will create a new
  4.     // instance of FooImpl for every injection.
  5.     binder.bind(Foo.class).to(FooImpl.class);
  6.     //绑定实例
  7.     // Bind Bar to an instance of Bar.
  8.     Bar bar = new Bar();
  9.     binder.bind(Bar.class).toInstance(bar);
  10.   }
  11. }

'     注入提供者
有时候并不是想注入一个实例 想在需要的时候再去获取 就可以注入一个Provider
只要是实现Provider接口的类 来实现提供需要的类
应用场景在那些特定的环境里 我们的业务代码依赖于其他容器或者运行状态中的实例 就需要在运行中才能注入 此时就需要自己实现一个提供者(Provider)来获取环境中实例 那么在业务代码中来注入这个Provider就可以了 
注意写法   这个自定义的类要 implements Provider<T>
例如
  1. class ServletContextProvider implements Provider<ServletContext> {
  2.     public ServletContext get() {
  3.         return ContextManager.getServletContext();
  4.     }
  5. }

绑定时
  1. bind(ServletContext.class).toProvider(ServletContextProvider.class);


然后在需要的时候调用 Provider<T> .get()方法来获取实例




'     configure方法里可以用install来安装别的Module的
......
比如
  1.     protected void configure() {
  2.         //install preceeding module(s)
  3.         install(new WebModule());
  4.         install(filtersModule);
  5.         //bind these servlet definitions to a singleton pipeline
  6.         bind(ManagedServletPipeline.class)
  7.                 .toInstance(new ManagedServletPipeline(servletDefinitions));
  8.     }


'     Injector的getInstance( type)将会返回一个泛型的实例
API里写到等价于 getProvider(type).get()


'     尽早的加载一个单体对象 它会自动把此类的依赖进行注入 只要在此类关联依赖包括依赖的依赖循环的依赖都会进行注入
  1. bind(xxx.class).asEageSingleton();


'     java 的class不能描述泛型 google提供了一个TypeLiteral
所以可以进行以下这样的绑定
  1. bind(new TypeLiteral<Set<Package>>(){}).toInstance(Collections.unmodifiableSet(new LinkedHashSet<Package>(packages)));
'     绑定自己本身为一个实例
bind(ManagedFilterPipeline.class)
                .toInstance(new ManagedFilterPipeline(filterDefinitions));
使用的时候
injector.getInstance(ManagedFilterPipeline.class)
                .initPipeline(servletContext, injector);

'     注入非接口实现类的 必须有一个构造函数有@Inject标记 要么就不要构造函数
例子
  1. package com.ergal.ezweb.core;

  2. import static com.google.inject.matcher.Matchers.annotatedWith;

  3. import java.util.LinkedHashSet;
  4. import java.util.Set;

  5. import org.apache.commons.logging.Log;
  6. import org.apache.commons.logging.LogFactory;

  7. import com.ergal.ezweb.annotation.ViewHtml;
  8. import com.ergal.ezweb.annotation.ViewPath;
  9. import com.ergal.ezweb.utils.ClassUtil;
  10. import com.google.inject.Inject;
  11. import com.google.inject.Provider;
  12. import com.google.inject.matcher.Matcher;


  13. /**
  14.  * 提供pagedesign的Provider
  15.  * @author <a href="mailto:ohergal@gmail.com">ohergal</a>
  16.  *
  17.  */

  18. public class PageDesignPaperBuilder implements Provider<Set<PageDesignPaper>>{
  19.     private static final Log log = LogFactory.getLog(PageDesignPaperBuilder.class);
  20.     
  21.     //符合视图annotation的匹配器定义
  22.     final Matcher<? super Class<?>> matcher = annotatedWith(ViewHtml.class).or(annotatedWith(ViewPath.class));
  23.     //只取视图类 所以重新定义一个集合
  24.     Set<Class<?>> pageClasses = new LinkedHashSet<Class<?>>();
  25.     
  26.     private Set<Package> packages;  //需要注入的包含所有视图的包
  27.     @Inject
  28.     public PageDesignPaperBuilder(Set<Package> packages){
  29.         this.packages = packages;
  30.     }
  31.     
  32.     public Set<Package> getPackages() {
  33.         return packages;
  34.     }
  35.     public void setPackages(Set<Package> packages) {
  36.         this.packages = packages;
  37.     }
  38.     public Set<PageDesignPaper> get(){
  39.         //实现返回一个PageDesignPaper的集合
  40.         return null;
  41.     }
  42.     
  43.     /**
  44.      * 取出所有的类 如果是视图page类 就组装一个PageDesignPaper的集合 
  45.      */
  46.     public PageDesignPaperBuilder install(){
  47.         //循环这个package的集合
  48.         log.info("******************** 开始扫描用户定义的视图类 ********************");
  49.         for(Package pack : packages){
  50.             //获取到所有的视图类
  51.             Set<Class<?>> classes = ClassUtil.getClasses(pack);
  52.             //循环所有类
  53.             for(Class<?> clazz : classes){
  54.                 if(matcher.matches(clazz)){
  55.                     //如果有视图定义的一些annotation 就添加到视图集合中
  56.                     pageClasses.add(clazz);
  57.                     log.info("添加自定义视图类: "+clazz.getName());
  58.                 }
  59.             }
  60.         }
  61.         log.info("******************** 扫描用户定义的视图类结束 ********************");
  62.         return this;
  63.     }
  64.     
  65. }

不能写成这样
  1. package com.ergal.ezweb.core;
  2. import static com.google.inject.matcher.Matchers.annotatedWith;
  3. import java.util.LinkedHashSet;
  4. import java.util.Set;
  5. import org.apache.commons.logging.Log;
  6. import org.apache.commons.logging.LogFactory;
  7. import com.ergal.ezweb.annotation.ViewHtml;
  8. import com.ergal.ezweb.annotation.ViewPath;
  9. import com.ergal.ezweb.utils.ClassUtil;
  10. import com.google.inject.Inject;
  11. import com.google.inject.Provider;
  12. import com.google.inject.matcher.Matcher;
  13. /**
  14.  * 提供pagedesign的Provider
  15.  * @author <a href="mailto:ohergal@gmail.com">ohergal</a>
  16.  *
  17.  */
  18. public class PageDesignPaperBuilder implements Provider<Set<PageDesignPaper>>{
  19.     private static final Log log = LogFactory.getLog(PageDesignPaperBuilder.class);
  20.     
  21.     //符合视图annotation的匹配器定义
  22.     final Matcher<? super Class<?>> matcher = annotatedWith(ViewHtml.class).or(annotatedWith(ViewPath.class));
  23.     //只取视图类 所以重新定义一个集合
  24.     Set<Class<?>> pageClasses = new LinkedHashSet<Class<?>>();
  25.     @Inject
  26.     private Set<Package> packages;  //需要注入的包含所有视图的包
  27.     
  28.     public PageDesignPaperBuilder(Set<Package> packages){
  29.         this.packages = packages;
  30.     }
  31.     
  32.     public Set<Package> getPackages() {
  33.         return packages;
  34.     }
  35.     public void setPackages(Set<Package> packages) {
  36.         this.packages = packages;
  37.     }
  38.     public Set<PageDesignPaper> get(){
  39.         //实现返回一个PageDesignPaper的集合
  40.         return null;
  41.     }
  42.     
  43.     /**
  44.      * 取出所有的类 如果是视图page类 就组装一个PageDesignPaper的集合 
  45.      */
  46.     public PageDesignPaperBuilder install(){
  47.         //循环这个package的集合
  48.         log.info("******************** 开始扫描用户定义的视图类 ********************");
  49.         for(Package pack : packages){
  50.             //获取到所有的视图类
  51.             Set<Class<?>> classes = ClassUtil.getClasses(pack);
  52.             //循环所有类
  53.             for(Class<?> clazz : classes){
  54.                 if(matcher.matches(clazz)){
  55.                     //如果有视图定义的一些annotation 就添加到视图集合中
  56.                     pageClasses.add(clazz);
  57.                     log.info("添加自定义视图类: "+clazz.getName());
  58.                 }
  59.             }
  60.         }
  61.         log.info("******************** 扫描用户定义的视图类结束 ********************");
  62.         return this;
  63.     }
  64.     
  65. }




  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值