すべてのコンポーネントをキャッシュする PicoContainer があります。すべてのコンポーネントをキャッシュするため、コンテナーのライフサイクルの適切な時点で、start
をstop
呼び出すことを期待しています。dispose
ただし、を使用してコンポーネントを構築するFactoryInjector
と、そのコンポーネントもキャッシュされているにもかかわらず、これらのメソッドがまったく呼び出されないことがわかりました。
次の例を見てください。
import java.lang.reflect.Type;
import org.picocontainer.Characteristics;
import org.picocontainer.DefaultPicoContainer;
import org.picocontainer.Disposable;
import org.picocontainer.MutablePicoContainer;
import org.picocontainer.PicoContainer;
import org.picocontainer.Startable;
import org.picocontainer.injectors.FactoryInjector;
public class PicoContainerFactoryTest {
public static void main(String[] args) {
MutablePicoContainer container =
new DefaultPicoContainer().as(Characteristics.CACHE);
try {
System.out.println("Adding components...");
container.addComponent(InstanceService.class,
new InstanceServiceImpl());
container.addComponent(ConstructedService.class,
ConstructedServiceImpl.class);
container.addAdapter(
new FactoryConstructedServiceAdapter());
System.out.println("Starting...");
container.start();
// Even this doesn't trigger it. :(
//container.getComponent(FactoryConstructedService.class);
System.out.println("Stopping...");
container.stop();
}
finally
{
System.out.println("Disposing...");
container.dispose();
}
}
public interface InstanceService
extends Startable, Disposable {}
public interface ConstructedService
extends Startable, Disposable {}
public interface FactoryConstructedService
extends Startable, Disposable {}
private static class InstanceServiceImpl extends Impl
implements InstanceService {
public InstanceServiceImpl() {
super("InstanceServiceImpl");
}
}
public static class ConstructedServiceImpl extends Impl
implements ConstructedService {
public ConstructedServiceImpl() {
super("ConstructedServiceImpl");
}
}
private static class FactoryConstructedServiceAdapter
extends FactoryInjector<FactoryConstructedService> {
public FactoryConstructedServiceAdapter() {
super(FactoryConstructedService.class);
}
@Override
public FactoryConstructedService getComponentInstance(
PicoContainer picoContainer, Type type) {
return new FactoryConstructedServiceImpl();
}
private static class FactoryConstructedServiceImpl extends Impl
implements FactoryConstructedService {
public FactoryConstructedServiceImpl() {
super("FactoryConstructedServiceImpl");
}
}
}
public static class Impl implements Startable, Disposable {
private final String name;
public Impl(String name) {
this.name = name;
System.out.println(" " + name + "#<init>");
}
@Override
public void start() {
System.out.println(" " + name + "#start");
}
@Override
public void stop() {
System.out.println(" " + name + "#stop");
}
@Override
public void dispose() {
System.out.println(" " + name + "#dispose");
}
}
}
これを実行した結果は次のようになります。
Adding components...
InstanceServiceImpl#<init>
Starting...
ConstructedServiceImpl#<init>
InstanceServiceImpl#start
ConstructedServiceImpl#start
Stopping...
ConstructedServiceImpl#stop
InstanceServiceImpl#stop
Disposing...
ConstructedServiceImpl#dispose
InstanceServiceImpl#dispose
というわけでstart()
、作成してインスタンスとして注入したコンポーネントが起動します。コンストラクター注入によって注入したコンポーネントが構築され、開始されます。しかし、工場経由で注入したコンポーネントからは何も見えません。
ドキュメントに関する限り、Javadoc for show FactoryInjector
、#start
および#stop
methods#dispose
は、ファクトリがスピンアウトするコンポーネントではなく、ファクトリ自体が独自のライフサイクル処理を実行することを目的としているようです。
ソースをざっと見てみると、アダプターの実装でComponentLifecycle
メソッドが呼び出されることがわかりますが、それをフックする方法がすぐにはわかりません。他の実装クラスを見ると、実際にはすべてが別のものに委譲されているようです。実際に何が起こっているのかを理解するのは困難です。
これを行う適切な方法は何ですか?これを行う適切な方法はありますか?