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

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

然后实际运用中
  1. MyAppapp=newMyApp();
  2. Modulemodule=newMyModule();
  3. Injectorin=Guice.createInjector(module);
  4. in.injectMembers(app);


这样就完成了一次注入

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

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

使用方法
createInjector(Stagestage, Module...modules)

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




  1. publicclassMyModuleimplementsModule{
  2. publicvoidconfigure(Binderbinder){
  3. //BindFootoFooImpl.Guicewillcreateanew
  4. //instanceofFooImplforeveryinjection.
  5. binder.bind(Foo.class).to(FooImpl.class);
  6. //绑定实例
  7. //BindBartoaninstanceofBar.
  8. Barbar=newBar();
  9. binder.bind(Bar.class).toInstance(bar);
  10. }
  11. }

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

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


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




' configure方法里可以用install来安装别的Module的
......
比如
  1. protectedvoidconfigure(){
  2. //installpreceedingmodule(s)
  3. install(newWebModule());
  4. install(filtersModule);
  5. //bindtheseservletdefinitionstoasingletonpipeline
  6. bind(ManagedServletPipeline.class)
  7. .toInstance(newManagedServletPipeline(servletDefinitions));
  8. }


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


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


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

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

  2. importstaticcom.google.inject.matcher.Matchers.annotatedWith;

  3. importjava.util.LinkedHashSet;
  4. importjava.util.Set;

  5. importorg.apache.commons.logging.Log;
  6. importorg.apache.commons.logging.LogFactory;

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


  13. /**
  14. *提供pagedesign的Provider
  15. *@author<ahref="mailto:[email protected]">ohergal</a>
  16. *
  17. */

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

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




你可能感兴趣的:(Guice)