On 13/07/2010, at 2:20 AM, Pete Muir wrote:
We definitely want something like this in WeldX.
However I would argue we should follow the design of interceptors much more closely.
1) The aroundInvoke method should take an InvocationContext, returning null for getTarget
(what is the reason for passing the proxy into the method in the design below)?
2) Drop the interface implementation requirement, and use the @AroundInvoke annotation
3) Add an annotation used to find the handlers e.g. @ServiceHandler
4) Add a meta-annotation @ServiceBinding(QueryInvocationHandler.class) @interface
QueryService {}
WDYT?
Looks good, I was planning on doing the meta-annotation stuff at some point, and using
AroundInvoke rather than implementing InvocationHandler is certainly an improvement.
I don't see why getTarget should return null though. Even though having access to the
object may not be not particularly useful, I think that most people would find this
behaviour surprising. Also they may want to call getClass() or use instanceof on the
object to determine the exact type they are dealing with.
Another point is that seeing as how we already have the Javassist dependency should this
be extended to work for abstract classes as well?
Stuart
On 28 Jun 2010, at 08:54, Stuart Douglas wrote:
> After some discussions with Walter White I have added some experimental code to weld
extensions to enable the automatic proxying of interfaces.
>
> To demonstrate how this works, here is a sample:
>
> @AutoProxy(QueryInvocationHandler.class)
> public interface QueryService<T> {};
>
> public interface UserQuery extends QueryService<User>
> {
>
> @Query("select u from user u where u.username=:1")
> public User findUserByUsername(String username);
>
> }
>
> public class QueryInvocationHandler implements InvocationHandler
> {
>
> @Inject EntityManager entityManager;
>
> public Object invoke(Object proxy, Method method, Object[] args)
> throws Throwable
> {
> //run the query based on the annotations on the method
> }
>
> }
>
> Any interface that extends QueryService will be automatically proxied by the
container, using the InvocationHander specified in the @AutoProxy annotation. This proxy
is registered as a bean, and if any qualifiers are present on the Interface being proxied
these are added to the bean. It is also possible to inject into the InvocationHandler.
> I also plan to make @AutoProxy a meta annotation, so the above could also be
represented as:
>
>
> @AutoProxy(QueryInvocationHandler.class)
> public @interface QueryService{}
>
> @QueryService
> public interface UserQuery
> {
>
> @Query("select u from user u where u.username=:1")
> public User findUserByUsername(String username);
>
> }
>
> Does all this sound ok, or does it not have a strong enough use case to include it in
Weld Extensions?
>
> Stuart