Introduction
Authors: Aslak Hellesoy, Jon Tirsen
Basics
This is a quick introduction to PicoContainer’s most important features. Read through it to get an idea of what PicoContainer is and isn’t.
PicoContainer’s most important feature is its ability to instantiate arbitrary objects. This is done through its API, which is similar to a hash table. You can put java.lang.Class objects in and get object instances back.
Example:
MutablePicoContainer pico = new DefaultPicoContainer();
pico.addComponent(ArrayList.class);
List list = pico.getComponent(ArrayList.class);
(i) MutablePicoContainer API
This code does the same as this:
List list = new ArrayList();
With a trivial example such as this there is no point in using PicoContainer. This was just to illustrate the basic API. PicoContainer becomes useful with larger number of classes and interfaces having complex dependencies between each other:
Complex Dependencies
Juicer Example
|
|
(Green means class, Yellow means interface). PicoContainer identifies dependencies by looking at the constructors of registered classes ( Constructor Injection ). PicoContainer can also be though of as a generic factory that can be configured dynamically. PicoContainer is able to instantiate a complex graph of several interdependent objects.
Write some simple classes and interfaces with dependencies
The “Juicer Example” diagram above could translate to the following code (we added a concrete Peelable):
public interface Peelable {
void peel();
}
public class Apple implements Peelable {
public void peel() { }
}
public class Peeler implements Startable {
private final Peelable peelable;
public Peeler(Peelable peelable) {
this.peelable = peelable;
}
public void start() {
peelable.peel();
}
public void stop() { }
}
public class Juicer {
private final Peelable peelable;
private final Peeler peeler;
public Juicer(Peelable peelable, Peeler peeler) {
this.peelable = peelable;
this.peeler = peeler;
}
}
(Note that this code suffers from the anti-pattern Propagating Dependency but let’s not worry about that for now )
Assemble components
You tell PicoContainer what classes to manage by registering them like this (the order of registration has no significance):
MutablePicoContainer pico = new DefaultPicoContainer();
pico.addComponent(Apple.class);
pico.addComponent(Juicer.class);
pico.addComponent(Peeler.class);
(i) MutablePicoContainer API
Instantiate components
You can tell PicoContainer to give you an instance of a class like this (provided it has been registered previously):
Juicer juicer = (Juicer) pico.getComponent(Juicer.class);
This will cause PicoContainer to do something similar to this behind the scenes (except that PicoContainer uses reflection):
Peelable peelable = new Apple();
Peeler peeler = new Peeler(peelable);
Juicer juicer = new Juicer(peelable, peeler);
return juicer;
Note how PicoContainer figures out that Apple is a Peelable, so that it can be passed to Peeler and Juicer’s constructors.
Container hierarchies
PicoContainer provides a powerful alternative to the Singleton . With container hierarchies you can create singleton-like objects where you have fine grained control over the visibility scope of the instance. (The singleton pattern is static and global – it won’t allow more than one instance, and it is visible from anywhere. Not nice when you try to build a large enterprise application from it).
A container (and its registered components) can get access to components registered in a parent container, but not vice-versa. Consider this example, using the classes from above:
THIS WON’T WORK! It is for illustration purposes only!
// Create x hierarchy of containers
MutablePicoContainer x = new DefaultPicoContainer();
MutablePicoContainer y = new DefaultPicoContainer( x );
MutablePicoContainer z = new DefaultPicoContainer( y );
// Assemble components
x.addComponent(Apple.class);
y.addComponent(Juicer.class);
z.addComponent(Peeler.class);
// Instantiate components
Peeler peeler = (Peeler) z.getComponent(Peeler.class); // WON'T WORK! peeler will be null
peeler = (Peeler) x.getComponent(Peeler.class); // WON'T WORK! This will throw an exception
Juicer juicer = (Juicer) y.getComponent(Juicer.class);
This can be visualised as follows:
Let’s analyse what will happen here:
- Line 12 will work fine. z will be able to resolve the dependencies for Peeler (which is Fruit) from the parent container.
- Line 14 will return null, as x can’t see Peeler.
- Line 16 will throw an exception, since Juicer’s dependency to Peeler can’t be satisfied (z can’t be seen by y).
Since this obviously won’t work, keep in mind that this was just an exercise to illustrate how container hierarchies work. For a more concrete example of the usage of container hierarchies, see PicoContainer Web .
Lifecycle
PicoContainer has support for Lifecycle . If your classes implement Startable , you can control the lifecycle of all your objects with a simple method call on the container. The container will figure out the correct order of invocation of start()/stop() all the objects managed by the container.
Calling start() on the container will call start() on all container managed objects in the order of their instantiation. This means starting with the ones that have no dependencies, and ending with the ones that have dependencies on others:
MutablePicoContainer.start()
MutablePicoContainer.stop()!
|
|
Lifecycle also works for hierarchies of containers. Calling start() on a container with child containers will start all the containers in a breadth-first order, starting with itself. Likewise, calling stop() will call stop() on all containers in the hierarchy in a depth-first order. The pictures below show what happens when start() and stop() are called on a container with children.
MutablePicoContainer.start()
MutablePicoContainer.stop()
|
|
In order for hierarchy-aware lifecycle to work, child containers must be registered as components in their parent container. Just creating a container with another one as a parent will not cause the parent container to know about the child container.
Example
MutablePicoContainer parent = new DefaultPicoContainer(new Caching());
MutablePicoContainer child = new DefaultPicoContainer(parent); // We must let the parent container know about the child container.
parent.addComponent(child); // This will start the parent, which will start the child.
parent.start();
Lifecycle is really only going to work for PicoContainers that are also caching component instances. Caching was a default in PicoContainer 1.x, but is not for 2.x – be warned!
Calling lifecycle methods on a container that has a parent container will not propagate the lifecycle to the parent container.
Read more about lifecycle here .
Contrasting Usage Styles
With PicoContainer you add components and get instances out in two styles.
Classic bean style:
pico = new DefaultPicoContainer();
pico.addComponent(ComponentOneImpl.class) // by type
pico.addComponent(ComponentTwoImpl.class) // by type
pico.addComponent(new ComponentThreeImpl()) // by instance
pico.addComponent(ComponentFourImpl.class) // by type
ComponentFourImpl four = pico.getComponent(ComponentFourImpl.class);
Or you can use a fluent style if you want:
ComponentFour four = new DefaultPicoContainer().addComponent(ComponentOne.class)
.addComponent(ComponentTwo.class).addComponent(new ComponentThree())
.addComponent(ComponentFour.class).getComponent(ComponentFour.class);
分享到:
相关推荐
通讯部分会讲解Galil_IOC-7007与上位机或其他设备的通信协议,如串行通信(RS-232、RS-485)、以太网通讯、USB连接等。用户将了解如何配置通讯参数,实现数据传输,并可能涉及到TCP/IP、UDP、MODBUS等通信协议的应用...
虽然描述部分并未提供具体的信息,但从标题中可以明确看出这是关于Spring框架的知识讲解。接下来,我们将详细介绍Spring框架的基础概念、核心特性以及它在实际开发中的应用。 ### Spring框架概述 Spring框架是一个...
本文将深入讲解Spring核心的技术点,包括IoC容器、Bean定义以及配置元数据等。 1. **IoC容器** IoC容器是Spring的核心,它负责管理和装配应用对象。通过IoC,容器控制着对象的生命周期和对象之间的依赖关系,而...
这个压缩包文件"Spring中文 开发手册+aop讲解.zip"显然包含了丰富的Spring框架学习资源,特别是对于那些希望深入理解和使用AOP(面向切面编程)概念的开发者来说。以下是这些资源可能涵盖的关键知识点: 1. **...
标题:“pro_spring_3.pdf(英文原版非扫描 看到小便知)”指的是《Pro Spring 3》,这本书是关于Spring框架的详细讲解书籍。它以其全面性和深度,被认为是学习Spring技术的一个重要资源。 描述:“学习spring的...
1. **Spring概述**:介绍Spring框架的基本概念,包括依赖注入(Dependency Injection, DI)和控制反转(Inversion of Control, IoC),这是Spring的核心设计原则。 2. **Spring容器**:详细解析了Spring的Bean工厂...
书中深入讲解了Spring 3以及相关辅助框架的最新技术,涵盖了Spring IoC容器以及它为开发者提供的全面组件模型。这本书不仅对概念性知识进行了详尽的阐述,还提供了丰富的代码示例,帮助开发者将理论知识应用到实际...
作为一本英文原版,它为中文读者提供了直接接触原汁原味的技术文献的机会,有助于提升对Spring框架的深入理解。 Spring框架是Java企业级应用开发中的基石,它提供了一整套服务,包括依赖注入、AOP(面向切面编程)...
需要注意的是,本书使用了一些英文缩写词汇,例如IoC、DI、AOP等,这些都是Spring框架中非常核心的概念。IoC(控制反转)是指将对象的创建和管理从传统硬编码中解放出来,由外部容器控制;DI(依赖注入)是IoC的一种...
2. **Wicket框架**:会讲解Wicket如何提供组件化的开发模式,使网页更加动态,以及它如何处理用户的输入和更新页面状态。 3. **Spring框架**:将介绍Spring框架的IoC容器、AOP(面向切面编程)特性,以及如何在食品...
- **英语能力**:虽然阅读英文版可能对部分读者来说比较吃力,但考虑到中文版可能存在的翻译问题,建议有一定的英语基础以更好地理解原文。 - **实践结合理论**:在学习本书的同时,尝试动手实现书中的示例项目,...
Spring框架是Java开发领域中最广泛使用的轻量级框架之一,以其模块化、可扩展性和对IoC(Inversion of Control,控制反转)及AOP(Aspect Oriented Programming,面向切面编程)的支持而闻名。本资源包含Spring的...
标题“Spring in Action英文版”和描述“Spring in Action”是该书的主体,它由Craig Walls和Ryan Breidenbach著作,旨在介绍Spring框架的核心概念和实用技巧。这本书分为三个部分,分别是Spring的基础、业务层的...
IoC是一种设计原则,用于实现对象间的依赖关系的倒置,从而减少模块间的耦合性。AOP则是允许开发者将横切关注点(如日志、事务管理等)从业务逻辑代码中分离出来,以提高模块化。 本书详细介绍了Spring框架的各个...
此书分为第四版英文版和第三版中文版,旨在帮助开发者全面掌握Spring的核心概念和技术。 第四版《Spring in Action》详细介绍了Spring 4.x版本的新特性,包括: 1. **Spring Boot**: 引入了Spring Boot,这是一个...
Spring框架是Java开发中最常用的轻量级开源框架之一,它以IoC(Inversion of Control,控制反转)和AOP(Aspect Oriented Programming,面向切面编程)为核心,极大地简化了企业级应用的开发工作。这份"Spring学习...
《Spring Persistence with Hibernate》这本书详细讲解了如何利用Spring和Hibernate两个强大的框架来构建高效的持久层解决方案。通过对Spring框架基础、Hibernate基础以及它们之间集成的最佳实践的学习,读者可以...
由于标题中明确提到是英文原版书籍,因此下文将围绕Spring框架的内容进行知识点的展开。 Spring框架是Java领域中广泛使用的一个开源框架,它的发展起源于对现有J2EE开发模式的反思和对轻量级容器的追求。Spring旨在...
《Spring In Action》是一本深度剖析Spring框架的权威著作,无论是中文版还是英文版,都是IT开发者们深入理解和掌握Spring框架的重要参考资料。该书详细介绍了Spring框架的各种功能和使用技巧,帮助开发者提升在实际...