JBoss development,
A new message was posted in the thread "Proxy SPI":
http://community.jboss.org/message/526000#526000
Author : jaikiran pai
Profile :
http://community.jboss.org/people/jaikiran
Message:
--------------------------------------------------------------
Based on our discussion yesterday about a need for a proxy-spi, here's what my initial
thoughts are. The following SPI keeps in mind both nointerface view (which uses Javassist)
and the other business view (which use j.l.r.Proxy).My initial thoughts around this were,
to have a ProxyFactory which at the minimum has this:
public interface ProxyFactory{ /** * Creates a proxy which is castable to the
interfaces passed and associates * the passed invocationHanlder with the proxy */
Object createProxy(Class[] interfaces, InvocationHandler invocationHandler);...}
With this, we could then have had a JavaReflectProxyFactory which would return
Proxy.newInstance(...) and a JavassistProxyFactory which would do its own proxy creation
logic. Note that currently the Javassist proxy factory for nointerface view uses a
j.l.r.InvocationHandler, but that's a implementation detail, and as such should not be
exposed through the SPI. i.e. the createProxy shouldn't ideally be expecting a
j.l.r.InvocationHandler as a param. Also, if other proxy factory implementations need some
more contextutal information for creation of proxies, then the above SPI will not be
sufficient.So i thought about something like this one:
/** * A {@link ProxyFactory} is responsible for creating proxies which are castable to *
the {@link Class}(es) specified in the {@link ProxyCreationContext#getTypes()} *
* Implementations of {@link ProxyFactory} can expect more contextual information * for
proxy creation, through custom {@link ProxyCreationContext}. *
*
* @see ProxyCreationContext#getTypes()
* @author Jaikiran Pai
* @version $Revision: $
*/
public interface ProxyFactory
{
/**
* Creates and returns a proxy which is castable to the {@link Class}(es) specified in
the passed
* proxyCreationContext.
*
* @param proxyCreationContext Contextual information for creating of proxies
* @return Returns a proxy which is castable to the {@link Class}(es) specified in the
passed proxyCreationContext
* @see ProxyCreationContext#getTypes()
*/
Object createProxy(T proxyCreationContext);
}
/**
* {@link ProxyCreationContext} holds the contextual information required for
* creation of a proxy.
* * Minimally, during the proxy creation, a {@link ProxyFactory} needs to know the *
{@link Class}(es) to which the resultant proxy is castable to. The {@link #getTypes()} *
returns this information. *
* @see JavaReflectProxyCreationContext
* @author Jaikiran Pai
* @version $Revision: $
*/
public interface ProxyCreationContext
{
/**
* Returns the {@link Class}(es) to which the proxy created by the {@link
ProxyFactory}
* should be castable to.
* @return
*/
Class[] getTypes();
}
So we have a ProxyFactory which has a createProxy method which accepts a
ProxyCreationContext. A minimal ProxyCreationContext provides only the getTypes() (which
is the Class types to which the resultant proxy should be castable). (I think we might
need a getClassLoader() too, but that can be discussed later).
Now, a j.l.r based proxy factory will also need a InvocationHandler for associating it
with the proxy it creates. So we could have a:
/**
* A {@link JavaReflectProxyCreationContext} in addition to {@link #getTypes()}
* also provides a {@link InvocationHandler} as a contextual information for
* proxy creation. The {@link InvocationHandler} is then associated with the
* proxy created by a call to {@link
JavaReflectProxyFactory#createProxy(JavaReflectProxyCreationContext)}
*
* @author Jaikiran Pai
* @version $Revision: $
*/
public interface JavaReflectProxyCreationContext extends ProxyCreationContext
{
/**
* Returns a {@link InvocationHandler} which will be associated to the
* proxy created by a call to {@link
JavassistProxyFactory#createProxy(JavassistProxyCreationContext)}
* @return
*/
InvocationHandler getInvocationHandler();
}
and then the j.l.r proxy factory implementation would be :
public class JavaReflectProxyFactory< T extends JavaReflectProxyCreationContext>
implements ProxyFactory
{
/**
* @see
org.jboss.ejb3.proxy.spi.ProxyFactory#createProxy(org.jboss.ejb3.proxy.spi.ProxyCreationContext)
*/
@Override
public Object createProxy(T proxyCreationContext)
{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Proxy.newProxyInstance(loader,
proxyCreationContext.getTypes(), proxyCreationContext.getInvocationHandler());
}
}
Similarly a Javassist based proxy factory (co-incidentally) expects a InvocationHandler
for proxy creation. So it too would have a:
/**
* A {@link JavassistProxyCreationContext}, in addition to {@link #getTypes()}
* also provides a {@link InvocationHandler} as a contextual information for
* proxy creation. The {@link InvocationHandler} is then associated with the
* proxy created by a call to {@link
JavassistProxyFactory#createProxy(JavassistProxyCreationContext)}
*
* @author Jaikiran Pai
* @version $Revision: $
*/
public interface JavassistProxyCreationContext extends ProxyCreationContext
{
/**
* Returns a {@link InvocationHandler} which will be associated to the
* proxy created by a call to {@link
JavassistProxyFactory#createProxy(JavassistProxyCreationContext)}
* @return
*/
InvocationHandler getInvocationHandler();
}
and the proxy factory implementation would look like:
public class JavassistProxyFactory implements ProxyFactory
{
/**
* @see
org.jboss.ejb3.proxy.spi.ProxyFactory#createProxy(org.jboss.ejb3.proxy.spi.ProxyCreatorContext)
*/
@Override
public Object createProxy(T proxyContext)
{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// do some
javassist logic and create a proxy
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object proxy =
blah();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// associate with
the invocation handler
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;associate(proxy,
proxyContext.getInvocationHandler());
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return
proxy;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
}
}
These factories could then be used by the (JNDI binder) clients like this:
public class NoInterfaceJNDIBinder
{
bindProxy()
{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// create
proxy
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ProxyFactory
proxyFactory = new JavassistProxyFactory();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JavassistProxyCreationContext
context = null; // create a JavassistProxyCreationContext
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object proxy =
proxyFactory.createProxy(context);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// bind to jndi
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ctx.bind(proxy);
}
}
And the other jndi binder could do:
public class LocalBusinessViewJNDIBinder
{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bindProxy()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//
create j.l.r based proxy
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ProxyFactory
proxyFactory = new JavaReflectProxyFactory();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JavaReflectProxyCreationContext
context = null; // create a JavaReflectProxyCreationContext
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxy
= proxyFactory.createProxy(context);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//
bind
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ctx.bind(proxy);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
}
Thoughts?
By the way, feel free to suggest a different name for the interfaces wherever applicable -
i am not good at naming.
--------------------------------------------------------------
To reply to this message visit the message page:
http://community.jboss.org/message/526000#526000