<delurk/>
On Thu, 6 Jun 2002, Berin Loritsch wrote:
<snip/>
> interface ComponentManager
> {
> Object lookup(String role);
> Object lookup(String role, Object hint);
> boolean exists(String role);
> boolean exists(String role, Object hint);
> }
>
> If you notice, there are four distinct differences from the current
> ComponentManger:
<snip/>
> 4) We remove the release() method altogether.
With a combination of dynamic proxies and the Object.finalize() method
it should be possible to use the VM's garbage collector to release a
component. This would be transparent to both the client and the
component.
how this could work:
- cm.lookup() returns a dynamix proxy implementing the interfaces of
the desired component. This proxy will pass all interface calls onto
the real component.
- neither the container nor the component manager keep a reference to
the proxy (they are allowed a weak reference -- but we want the VM's
GC to tell us when the client nolonger holds a reference to it.
- the client uses the component (transparently via the proxy).
- when the client loses all references to the proxy the GC will call
the finalize() mothod on the proxy. This method will do what the
cm.release() method currently does.
[note: it is the proxy that gets garbage collected, not the component]
how the code might look:
class ReleasingProxy implements java.lang.reflect.InvocationHandler
{
private Object component;
public ReleasingProxy( Object o )
{
component = o;
}
public Object invoke( Object proxy, Method method, Object[] args )
throws Throwable
{
try
{
return method.invoke( component, args );
}
catch ( InvocationTargetException e )
{
throw e.getTargetException();
}
}
protected void finalize()
{
// code from cm.release() goes here.
}
}
in the lookup code 'return component;' can be replaced with:
// may want to filter out the lifecycle interfaces...
// they don't hurt, but it might be nice if they weren't
// exposed to the client
Class[] interfaces = component.getClass().getInterfaces();
return java.lang.reflect.Proxy.newProxyInstance(
classLoader,
interfaces,
new ReleasingProxy( component )
);
[note: the ReleasingProxy will probably also need a reference to the
Container for doing the release]
Advantages:
- everything happens transparently to the client and the component
- the release code is only called after the client has lost all
references to the proxy (this actually makes it safer than using
cm.release())
Disadvantages:
- the release code is only called after the client has lost all
references to the proxy.
- relies on the VM's GC to return the component to the pool, and it is
unclear how long this will take. [I don't know much about GC
implementations, but theoretically if there are no circular references
the reference count can become 0 and the VM can remove the object
immediately]
- requires JDK 1.3
- adds extra indirection to each component method call, and creates a
couple of extra objects on each lookup
Robert.
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, email: [EMAIL PROTECTED]