本篇主要介绍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!