`
ihuashao
  • 浏览: 4725493 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

魅力四射的“小玩意”——PicoContainer

阅读更多

Jon Tirsen在他的weblog里说,他看到一个叫PicoContainer的有趣项目,并立刻投身其中。这个自称“IoC(Inversion of Control)type 3”的微容器有什么吸引人的魅力?

PicoContainer / NanoContainer I've recently joined two new projects:
http://www.picocontainer.org
http://www.nanocontainer.org

The founders of the project are Paul (AltRMI, Enterprise Object Broker) and Aslak (XDoclet, MiddleGen). Actually they pair-programmed most of it at Paul's place and a lot of beer was involved. The end result: a neat, simplistic and wonderfully TDDed piece of work. Joe (SiteMesh, QDox), my unit-testing guru, is also in on it.

It's basically an Inversion-of-Control-container/framework/micro-kernel. Pico will be the simplistic micro-kernel and Nano will be a bunch of containers serving different purposes (most built on top of Pico).

I'm not an IoC-expert by any means, and, well, I didn't know much about it before chatting with Paul and Aslak. The cool (and quite controversial) thing is that Pico (at least by default) implements style 3 IoC, which means constructors are used to define dependencies. Smart!

I will implement some Nanning support in Nano so that aspects can define dependencies on services and the container will resolve them properly, the aspects will also be able to aspectify the components transparently. The details are far from finalized, just a bunch of semi-digested ideas. I'll give you a couple of use-cases though. An aspect implementing transparent persistence with Prevayler could retrieve it's Prevayler-instance just by declaring it in its constructor:

public class PrevaylerAspect {
  public PrevaylerAspect(Prevayler prevayler) { /* ... */ }
  /* ... */
}

A declarative transaction aspect could declare it's dependency on a TransactionManager by:

public class TransactionAspect {
  public TransactionAspect(TransactionManager transactionManager) { /* ... */ }
  /* ... */
}

Put these aspects along with their services in a container, Pico does it's work and all components are properly assembled:

PicoContainer pico = new HierarchicalPicoContainer.Default();

pico.registerComponent(RemoteTransactionManagerImpl.class);
pico.registerComponent(PicoPrevayler.class);
pico.registerComponent(PrevaylerAspect.class);
pico.registerComponent(TransactionAspect.class);

pico.start();

Neat and simple. No XML, no runtime attributes, no fuss.

Another great thing is that it's brilliant to mock-test the things. Say you want to mock-test your TransactionAspect to see that it actually demarcates it's transactions properly:

MockTransactionManager mockTransactionManager = new MockTransactionManager();
// ...set up expectations and so forth...
TransactionAspect transactionAspect = new TransactionAspect(mockTransactionManager);
AspectSystem aspectSystem = new AspectSystem();
aspectSystem.addAspect(transactionAspect);
TestObject testObject = (TestObject) aspectSystem.newInstance(TestObject.class);
// ...run your tests on your testObject...
mockTransactionManager.verify();

Check it, you'll like it! (2003-06-20 11:25:47.0)

无独有偶,我的另一位偶像Rickard Oberg也看上了这个项目。他在自己的weblog上介绍了PicoContainer和IOC,还为这个跟人吵起来了。这个小玩意的价值在哪里?我很信赖Oberg的见地。
Why IoC? From the comments on the PicoContainer entry it seems like people are not quite getting what's so great about IoC (Inversion of Control). "If all it does is lookup, what's the point?". 

To me this question is like saying "What's the point with aircraft? The only thing they do is fly", but I'll give you an example that might highlight why IoC is nice to have. Let's say you have a component A that uses a component B to do something. In the first iteration of your application both are just POJO's registered in a PicoContainer. Here's the code for A:

public class A
{
  B comp;
  public A(B comp)
  {
    this.comp = comp;
  }

  public String helloWorld()
  {
    return "Hello "+comp.world();
  }  
}
PicoContainer will, using IoC, get a reference to B and hand it to A so that it can run. Let's say that we now change so that B is a Jini service that is located using Jini discovery. The code for A now looks like this:
public class A
{
  B comp;
  public A(B comp)
  {
    this.comp = comp;
  }

  public String helloWorld()
  {
    return "Hello "+comp.world();
  }  
}
Looks familiar, doesn't it? But, Jini isn't all that popular these days so we changed B into a webservice and put some failover on top of it using grid computing. With all of this new high-tech stuff running the show, the code for A now looks like this:
public class A
{
  B comp;
  public A(B comp)
  {
    this.comp = comp;
  }

  public String helloWorld()
  {
    return "Hello "+comp.world();
  }  
}
See my point? The code for the A component has not changed one bit even though the lookup and discovery infrastructure has changed radically over the lifetime of our application. This is what IoC brings to the table, and which is what PicoContainer has implemented in a such an elegant way that you don't have to read a lengthy architectural document to grasp how it works.

That's the point.

(NOTE: For those who want to be picky about the above example and say that changing a service to a remote one and evolve it to use transactions and whatnot which would change the code for A, all I can say is: 1) you're missing the point 2) use AOP) (2003-06-29 09:36:39.0)

分享到:
评论

相关推荐

    PicoContainer源码学习日志

    PicoContainer相比于Spring、Guice等大型框架,体积小、启动快,适合小型项目或嵌入式环境。然而,它的功能相对较少,不支持高级特性如AOP(面向切面编程)和更复杂的依赖解析策略。 五、源码学习要点 1. 查看...

    Android代码-picocontainer

    PicoContainer 3.x is in Git at Github and Codehaus (mirrors), and is a work in progress. PicoContainer 3.x is good enough to use in production, but it is not finished yet. Goals over 2.x The major ...

    picocontainer:Java微容器

    相比于Spring、Guice等更全面的DI框架,Picocontainer更小、更快,但功能相对较少。对于那些希望避免大型框架复杂性的开发者来说,Picocontainer是一个不错的选择。 7. **学习资源** 要深入了解Picocontainer,...

    cucumber-picocontainer-example

    CucumberPicoContainer示例开发环境安装Git( ) 安装JDK 1.5+( 或 ) 安装Maven 3( )下载git clone git@github....jar target/cucumber-picocontainer-example-jar-with-dependencies.jar

    Ioc模式和微容器——j道

    在这个例子中,`B`类的实例是由PicoContainer创建的,同时它也会自动处理`B`类所需的`AInterface`实例。 ##### Spring Framework Spring 是一个广泛使用的Java企业级应用开发框架,它提供了强大的依赖注入功能。 ...

    cake-picocontainer-1.3.jar

    jar包,亲测可用

    cake-picocontainer-1.3-sources.jar

    jar包,亲测可用

    coconut-internal-picocontainer-1.3.jar

    jar包,官方版本,自测可用

    vertx-pico-support:vert.x 的 PicoContainer 支持

    PicoContainer 支持 vert.x 使用依赖注入。 用法 创建一个垂直: public class MyVerticle extends Verticle { public void start() { ApplicationContext applicationContext = ApplicationContext.create() ....

    深入浅出struts2

    最后,依赖注入也成了Struts2王国中的一等公民,这项功能是通过Spring框架的插件和Plexus共同提供的,与PicoContainer的结合工作还正在进行中。 本书的目的,是为了帮助读者掌握Struts2框架,并能够对组成框架的功能...

    Java轻量级容器的比较.pdf

    Java轻量级容器,如Spring、HiveMind和PicoContainer,是为了降低系统组件间的耦合度而设计的。它们都采用了依赖注入这一核心设计模式,但在实现方式和哲学上各有不同。 **Spring Framework** 是一个功能全面的轻量...

    DI容器框架Google Guice与Spring框架的区别

    这个标题表明我们要探讨的是两种不同的依赖注入(Dependency Injection,简称DI)容器——Google Guice和Spring框架之间的差异。DI是一种设计模式,它帮助开发者在对象之间解耦,使得代码更加灵活、可测试和可维护。...

    jbehave-pico-3.9-beta-4.zip

    JBehave 集成了多种依赖注入框架,其中 PicoContainer 是一个轻量级的容器,用于管理对象的生命周期和依赖关系。3.9-beta-4 版本可能包含了对框架的改进和修复,以提供更稳定、高效的测试支持。 【描述】中的 "mod-...

    IoC 容器和Dependency Injection 模式

    - **PicoContainer**:PicoContainer 是一个轻量级的 IoC 容器,它的设计目标是简单易用。虽然没有 Spring 那么全面,但对于小型项目或简单的依赖管理来说已经足够。 #### 六、总结 IoC 容器和依赖注入模式是现代...

    JacORB安装包

    %JACORB_HOME%\lib\picocontainer-1.2.jar;%JACORB_HOME%\lib\slf4j-api-1.5.6.jar; %JACORB_HOME%\lib\slf4j-jdk14-1.5.6.jar;%JACORB_HOME%\lib\wrapper-3.1.0.jar; 修改PATH添加%JACORB_HOME%\bin

    Dependency Injection

    依赖注入通常与控制反转(Inversion of Control,简称IoC)联系在一起,因为它们共同作用于实现同一目标——使软件组件更加解耦、灵活和易于维护。 ### Java社区的轻量级容器 在Java社区中,随着对J2EE复杂性的...

    JdonFramework开源框架 v5.1 Build20071025_jdonframework(毕设 + 课设).zip

    3. **PicoContainer集成**:JdonPicoContainer是Jdon内置的轻量级容器,负责对象的生命周期管理和依赖注入。PicoContainer的轻量级特性使得框架运行更高效,同时保持了足够的灵活性。 4. **持久层支持**:虽然提供...

    struts2工作流程

    2. **过滤器处理**:请求经过一系列过滤器(Filter),其中第一个通常是Struts2的核心过滤器——`StrutsPrepareAndExecuteFilter`。该过滤器负责初始化Struts2环境,并准备执行相应的Action。此外,还可能包括其他...

Global site tag (gtag.js) - Google Analytics