且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

PicoContainer(Ioc容器)在测试用例中的应用(二)

更新时间:2022-06-28 00:16:09

本篇主要介绍PicoContainer的一些主要特性,很简单、很容易,但是很有效。喜欢英文的盆友也可以移步官方介绍,但是有些代码在新版本并不好使,还需要自己研究=.=!。

依赖注入

PicoContainer支持很多种注入方式,比如构造器注入、setter注入、annotation注入等等很多了。我们常用的annotation注入和构造器注入就可以了。

1、annotation注入方式

public class TestRandomWriteAndRead extends TestWriteAndRead {
  @Inject
  protected Writer writer;
  @Inject
  protected Reader reader;
  
  //...
}

  //...
  public void startTest(){
    PicoContainer pico = new DefaultPicoContainer();   
    pico.addComponent(RandomReader.class);
    pico.addComponent(RandomWriter.class);
    pico.addComponent(TestRandomWriteAndRead.class);
    
    TestWriteAndRead readAndWrite = pico.getComponent(TestWriteAndRead.class);
  }
2、构造器注入
 
public class TestRandomWriteAndRead extends TestWriteAndRead {
  protected Writer writer;
  protected Reader reader;
  
  public TestRandomWriteAndRead (Reader reader, Writer writer){
    this.writer = writer;
    this.reader = reader;
  }
  
  //...
}

//startTest方法同上
需要注意的是以上两种方式都是按照类型匹配注入的,如果pico容器中含有相同的两个类型对象就会报错。当然也可以按照名称来匹配注入。看下面的例子,pico会按照我们定义的名字,自动把reader和writer匹配到TestRandomWriteAndRead的构造函数中。
 
public class TestRandomWriteAndRead extends TestWriteAndRead {
  protected Writer writer;
  protected Reader reader;
  
  public TestRandomWriteAndRead (Reader reader, Writer writer){
    this.writer = writer;
    this.reader = reader;
  }
  
  //...
}

//...
public void startTest(){
  PicoContainer pico = new DefaultPicoContainer();   
  pico.addComponent("reader", RandomReader.class);
  pico.addComponent("writer", RandomWriter.class);
  pico.addComponent(TestWriteAndRead.class, TestRandomWriteAndRead.class,
      new ComponentParameter("reader"), new ComponentParameter("writer"));
  
  TestWriteAndRead readAndWrite = pico.getComponent(TestWriteAndRead.class);
}
单例模式
单例模式是我们常用的设计模式,在PicoContainer中用起来也非常简单,仅需要加入容器时标记一下即可,此时容器仅会初始化一个实例,并注入到需要他的地方。下面代码中RandomReader就使用了单例模式。
 
public void startTest(){
  PicoContainer pico = new DefaultPicoContainer();   
  pico.as(CACHE).addComponent(RandomReader.class);
  pico.addComponent(RandomWriter.class);
  pico.addComponent(TestWriteAndRead.class);
  
  TestWriteAndRead readAndWrite = pico.getComponent(TestWriteAndRead.class);
}
生命周期
PicoContainer有自己的生命周期管理,仅需要实现Startable接口即可,此接口提供了start和stop方法。当调用pico.start();时,容器就会调用start方法开始运行这些实现的start方法,stop同理。这个很有意思,前面讲我们可以像搭积木一样,在用例中加入各个操作模块,然后使用start()命令触发各个模块的运作,让整个系统run起来。
 
public class TestRandomWriteAndRead extends TestWriteAndRead implements Startable {
  //...
  
  @Override
  public void start() {
    //...
  }

  @Override
  public void stop() {
  }
}
其他功能
比如Scoped功能可以在一个容器下面建立子容器,各不同类型的Container(我们前面用的都是DefaultPicoContainer),各种高级功能。如果有兴趣可以共同研究探讨,我觉得既然使用轻量级的Ioc容器以上这些基本功能大体已经够了。Enjoy it!