Isn't this a chicken-and-the-egg problem? The CM must know which component
instance to call lookup() on! Perhaps if it was a static method that was
introspected, but I'm not sure that is a viable solution. JNDI has some
nifty solutions that might be possible to borrow from, e.g. the
Referenceable interface and the ObjectFactory/ObjectFactoryBuilder.

Regards,

--mike

On Thu, 20 Jun 2002, Robert Mouat wrote:

> here is a proposal that will allow us to:
> 
>   - have a well defined relationship between the container and
>   component managers [though it doesn't touch on the issue of
>   component resolving]
> 
>     + you could write component managers that will work in any
>     container - and be specified at assembly time.
> 
>     + these new component managers will work alongside the existing
>     component managers (allowing for a gentle upgrade path).
> 
>   - create dynamic proxies, for example:
> 
>     + tracing of component level method calls.
> 
>     + aaa (authentication, authorisation, and accounting), an aaa
>     proxy could intercept component level method calls.
> 
>     + release() via the VM's garbage collector.
> 
>     + sessions could be implemented this way (with only slight
>     modifications from my recent email).
> 
>   - possibly satisfy some of the need for custom markers (as long as
>   they are called after initialize). [sessions would probably fit this
>   category]
> 
>   - chain together any of the above (at the whim of the assembler).
> 
> this will work with version 4 (and 5) of the framework and shouldn't
> break anything currently in existence.
> 
> 
> ==== proposal: CustomLookup interface ====
> 
> the proposal is simply that we add the following interface to the
> framework:
> 
>   interface CustomLookup
>   {
>     public Object lookup();
>   }
> 
> with the contract:
> 
>   if a component implements the CustomLookup interface then upon
>   ServiceManager.lookup() a reference to the component is not
>   returned, but instead the result of the CustomLookup.lookup()
>   method is returned.
> 
> e.g. inside the ServiceManager the following:
> 
>   return component;
> 
> could be replaced with:
> 
>   if ( component instanceof CustomLookup )
>   {
>     return ((CustomLookup) component).lookup();
>   } else {
>     return component;
>   }
> 
> Note: the CustomLookup should probably have a release() method that
> is deprecated/removed with the ServiceManager.release().
> 
> Note: the CustomLookup.lookup() has no args (to prevent it from
> being used as a selector/directory/resolver)
> 
> I'd also like to make the following recommendation:
> 
>   in the absence of any other lifestyle indicator a component
>   implementing CustomLookup should be a singleton, otherwise a new
>   instance should be created upon every lookup.
> 
> Note: the container will still have to be able to handle these two
> lifestyles (single and per-lookup) but all others can be managed by
> CustomLookup components.
> 
> It shouldn't take much effort to implement this change.
> 
> 
> ==== example: component manager ====
> 
> note: component managers get the benefits of the lifecycle methods...
> 
> for simplicity: not dealing with synchronization, exceptions, and
> assuming that release() will get called.
> 
>   class PoolingComponentManager
>     implements CustomLookup, Parameterizable, Composable, Initializable
>   {
>     static final DEFAULT_SIZE = 5;
>     String m_role;
>     int m_size;
>     List m_pool;
>     ComponentManager m_cm;
> 
>     public void parameterize( Parameters parameters )
>     {
>       m_size = parameters.getParameterAsInteger( "size", DEFAULT_SIZE );
>       m_role = parameters.getParameter( "role", null );
>     }
> 
>     public void Compose( ComponentManager cm )
>     {
>       m_cm = cm;
>     }
> 
>     public void initialize()
>     {
>       m_pool = new ArrayList( m_size );
>     }
> 
>     public Object lookup()
>     {
>       if (! m_pool.isEmpty() )
>         return m_pool.remove( 0 );
>       else
>         return m_cm.lookup( m_role );
>     }
> 
>     public void release( Object component )
>     {
>       if ( m_pool.size() < m_size )
>       {
>         if ( component instanceof Recyclable )
>           ((Recyclable) component).recycle();
>         m_pool.add( component );
>       }
>       else
>         m_cm.release( component );
>     }
> 
>   }
> 
> To use the PoolingComponentManager on a component X the assembler
> could do the following...
> 
>   1. configure the pooling component manager so that it has parametes
>   role=X-role size=5
> 
>   2. configure the component locater so that a lookup that would have
>   resolved to X now resolves to the pooling component manager.  And
>   that when the pooling component manager looks up X-role it gets X.
> 
> Now whenever a client makes a request that would resolve to X, the
> request will go to the pooling component manager which will return a
> component from its pool or request X-role from the ComponentManager
> (if the pool is empty).
> 
> ==== example: dynamic proxy ====
> 
> here is an example of how a tracing proxy could be implemented (minus
> exception handling and synchronization)...
> 
>   class TracingProxy extends AbstractLogEnabled
>     implements CustomLookup, InvocationHandler, Composable, Parameterizable
>   {
>     String m_role;
>     String m_name;
>     ComponentManager m_cm;
>     Map m_ids = new WeakHashMap();
>     int count = 0;
> 
>     public void parameterize( Parameters parameters )
>     {
>       m_role = parameters.getParameter( "role", null );
>       m_name = parameters.getParameter( "name", "tracingProxy" );
>     }
> 
>     public void compose( ComponentManager cm )
>     {
>       m_cm = cm;
>     }
> 
>     public Object invoke( Object proxy, Method method, Object[] args )
>       throws Throwable
>     {
>       Object ret;
>       Object id = m_ids.get( proxy );
>       info( "Enter: " + method + " for " + m_name + "-" + id );
>       try
>       {
>         ret = method.invoke( m_component, args );
>       }
>       catch ( InvocationTargetException ite )
>       {
>         warn( "Error in: " + method " for " + m_name + "-" + id, ite );
>         throw ite.getTargetException();
>       }
>       info( "Leave: " + method + " for " + m_name + "-" + id );
>       return ret;
>     }
> 
>     public Object lookup()
>     {
>       Object component = m_cm.lookup( m_role );
>       Class[] interfaces = component.getClass().getInterfaces();
>       ClassLoader classLoader = component.getClass().getClassLoader();
>       Object proxy = java.lang.reflect.Proxy.newInstance(
>         classLoader, interfaces, this
>       );
>       m_ids.put( proxy, new Integer( ++m_count ) );
>       return proxy;
>     }
> 
>   }
> 
> 
> To activate the tracing on a component X the assembler could do the
> following...
> 
>   1. configure the tracing proxy so that it has parameters:
>   role=X-role, name=X-trace
> 
>   2. give the tracing proxy its own logger.
> 
>   3. configure the component locator so that a lookup that would have
>   resolved to X now resolves to the tracing proxy.  And that whenever
>   the tracing proxy looks up X-role it gets X.
> 
> Now whenever a client makes a request that would resolve to X they
> will get a proxy that will log all method calls, before passing them
> on.
> 
> ====
> 
> a SessionManagingProxy proxy can be created in a similar fashion to my
> recent email, with the change that the Proxy now runs the show (and
> the SessionEnabled component should probably let m_SessionManager
> default to an instance of SimpleSessionManager in case
> setSessionManager() isn't called).
> 
> ==== issues ====
> 
>   - it is now possible for the assembler to specify cyclic
>   dependencies when chaining Customlookup components together, this
>   may cause lookup() to hang.
> 
>   - unless you have something like:
> 
>       public Object lookup() { return this; }
> 
>    no other component will ever get a direct reference to the
>    CustomLookup component.  So I'm wondering if it is still correct to
>    refer to it as a component... perhaps meta-component might be
>    better... or since the dynamic proxies could fall into a broad
>    definition of component management, perhaps manager-component...
> 
>   - I don't know if 'CustomLookup' is a great name so feel free
>   to suggest others... MetaComponent?
> 
> Robert.
> 
> 
> --
> To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
> 


--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to