Implemented an experimental feature in the spirit of the @Proxy concept where 
an interface can be given along with an InvocationHandler implementation.

When the bean is created we'd create the InvocationHandler, create a proxy 
using the interface, then use the proxy as the bean instance.

Took this idea a bit further to allow for abstract classes to get the same perk 
and more.  If the bean class is abstract and implements 
java.lang.reflect.InvocationHandler, then the abstract methods will delegate to 
the bean's java.lang.reflect.InvocationHandler.invoke(..) method.

This allows for sort of a hybrid approach where some methods can be abstract 
and handled in a reflection-like manner, while others can be implemented 
regularly.

An interesting difference is the code takes extreme care to implement all the 
constructors of the parent class as well as the annotations of the parent class 
and any method annotations and method param annotations of abstract methods.

This should allow the dynamically created class to replace the parent class in 
every way, including usage in annotation heavy APIs like JAX-RS, JAX-WS or CDI. 
 I tested JAX-RS and it seems to work perfectly.

For example see this RESTful service:

    @Stateless
    @Path("/ejb")
    public abstract class RESTIsVeryCool implements InvocationHandler {

        @EJB
        private SimpleEJB simpleEJB;

        @javax.ws.rs.core.Context
        Request request;

        @Path("/normal")
        @GET
        public abstract String normal();

        @Path("/rest")
        @GET
        public abstract String rest();

        @Path("/param")
        @GET
        public String param(@QueryParam("arg") @DefaultValue("true") String p) {
            return p;
        }

        @Path("/field")
        @GET
        public boolean field() {
            return "GET".equals(request.getMethod());
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws 
Throwable {
            return simpleEJB.ok();
        }
    }


This is of course an experiment.  All sorts of feedback welcome!  We can go 
anywhere or nowhere with this :)


-David

Reply via email to