欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Guice2.0的变化——第一部分 新的特性(下)

程序员文章站 2022-03-14 08:33:54
...

 

Servlets

ServletModule 现在支持编程式的配置 servlets filters 。这些 servlets 可以直接被注入。

GuiceServletContextListener 类可以用来帮助 Guice 在一个 servlet 容器中来初始化 Guice 应用程序。同样,我也举个例子:

public class InjectedHttpServletTest extends TestCase {

  private static class MyDependency {}

  // 假设我的MyServlet依赖于MyDependency
  private static class MyServlet extends InjectedHttpServlet {
    @Inject MyDependency myDependency;
  }

  // 创建我的MyListener
  static class MyListener extends GuiceServletContextListener {
    protected Injector getInjector() {
      return Guice.createInjector();
    }
  }

  public void test() throws ServletException {

    ServletContext context = createFakeServletContext(attributes);
    ServletConfig config = createMock(ServletConfig.class);
    expect(config.getServletContext()).andReturn(context).atLeastOnce();
    replay(config);

    GuiceServletContextListener listener = new MyListener();
    listener.contextInitialized(new ServletContextEvent(context));
    assertEquals(1, attributes.size());

    MyServlet servlet = new MyServlet();
    servlet.init(config);
    verify(config);
    assertNotNull(servlet.myDependency);

    listener.contextDestroyed(new ServletContextEvent(context));
    assertTrue(attributes.isEmpty());
  }
  ...
}
 

 

Child Injectors

 

Injector.createChildInjector 允许你创建的子 injectors 继承父类的 bindings scopes interceptors converters 。该 API 的主要是为了扩展而准备的。看例子吧:

public void test() {
    Injector parent = Guice.createInjector(); //创建父Injector
Injector child = parent.createChildInjector();//创建子Injector
	//判断是否真的继承了父Injector
    assertSame(child.getInstance(A.class), parent.getInstance(A.class));

Injector anotherChild = parent.createChildInjector();//创建另一个子Injector
//判断是否继承的子Injector一致
    assertSame(anotherChild.getInstance(A.class), parent.getInstance(A.class));

Injector grandchild = child.createChildInjector();//创建一个孙子Injector
//判断是否孙子继承的Injector也一致
    assertSame(grandchild.getInstance(A.class), parent.getInstance(A.class));
  }
  ...

 

 

Even Better Error Reporting

Guice1.0 的时候,趋向于使用“又臭又长”的“ caused by ”来显示异常。现在我们已经好好的整理了这块。现在一个简单的异常就可以看出当错误发生时, Guice 的不俗表现了。

 

 

Introspection API

很像 java.lang.reflect API 允许你通过编程的方式重写一个 module ,将原来的绑定同新的绑定结合在一起。当然它还允许你查检一个已创建好的 injector ,看看里面绑定的是什么。这将会是你使用 Guice 的又一简单而又强大的扩展工具。看到这里,我马上想到了 Python 。不过,初步来看, API Doc 中貌似没有哪个类含有 Introspedtion 字眼。

 

 

Pluggable Type Converters

字符串常量绑定可以使用方便的类型转换,使之转换成任意类型(比如说转换成 dates URLs 或者 Colours

public void testOneConstantInjection() throws CreationException {
    Injector injector = Guice.createInjector(new AbstractModule() {
      protected void configure() {
        //将字符串常量“5”绑定到标注“@NumericValue”上
        bindConstant().annotatedWith(NumericValue.class).to("5");
        bind(Simple.class);
      }
    });

    Simple simple = injector.getInstance(Simple.class);
    assertEquals(5, simple.i);
  }

static class Simple {
    // 属性“i”使用了@NumericValue
    @Inject @NumericValue int i;
  }

 

 

OSGi-friendly AOP

Guice 是通过内部生成字节码的方式来实现 AOP 。在 Guice2.0 中,生成的 classes 通过一个桥接的 classloader 来装载,而这个 classloader 可以在一个类似于 OSGi 的托管环境。

 

 

Type Resolution

 

参数化的注入点( Parameterized injection points )允许你注入像 Reducer<T> Converter<A, B> 这样的类型。 Guice 会计算出 T 的实际类型,并且自动绑定上。 TypeLiteral injection 意味着你可以将一个 TypeLiteral<T> 注入到你的类中。不过要使用这个特性,还得依赖于 Java5 的泛型擦除技术。现在 TypeLiteral 类中的方法就提供了手动类型解决方案。说实话,看完下面的泛型使用,我有点头皮发麻的感觉。

public void testWildcards() throws NoSuchFieldException {
    TypeLiteral<Parameterized<String>> ofString = new TypeLiteral<Parameterized<String>>() {};

    assertEquals(new TypeLiteral<List<String>>() {}.getType(),
        ofString.getFieldType(Parameterized.class.getField("t")).getType());
    assertEquals(new TypeLiteral<List<? extends String>>() {}.getType(),
        ofString.getFieldType(Parameterized.class.getField("extendsT")).getType());
    assertEquals(new TypeLiteral<List<? super String>>() {}.getType(),
        ofString.getFieldType(Parameterized.class.getField("superT")).getType());
  }

  static class Parameterized<T> {
    public List<T> t;
    public List<? extends T> extendsT;
    public List<? super T> superT;
  }

...

 

 

 

 

第一部分结束..........