After some lengthy discussion in WELD-2533, and thanks to Xavier Dury, I think it is possible to enhance the capabilities of InterceptionFactory on interfaces by not enforcing the proxyability (and constructor) requirements while staying aligned with CDI spec. As it stands:
- CDI spec says that If the type of the instance is not proxyable as defined in Unproxyable bean types an UnproxyableResolutionException exception is thrown.
- I found no CDI TCK test that would cover this specifically
- But CDI spec also says that If an injection point of type InterceptionFactory has a type parameter that is not a Java class, non-portable behavior results.
- This in theory negates the previous sentence and loosens the requirements
Currently (Weld 3.1.0.Beta1) we allow to have interface as parameter of IntercerceptionFactory<T> but we enforce that the actual instance provided by user is proxyable. Pros:
- Interceptor bindings are taken from both, your changes via configurator on interface as well as those that were already placed on the implementation class
Cons:
- You still cannot intercept anything that isn't proxyable, e.g. has constructor with args only, is final etc.
There was a suggestion to implement this differently, not extending the original class and hence bypassing the proxyability requirements. This was by Xavier Dury in this PR (and this fork). A decompiled proxy using this approach looks like this Pros:
- Loosens limitations of InterceptionFactory, you can now work on unproxyable instances
- Not only it loosens IF limitation, it also relaxes requirements on proxyability of normal scoped beans as the interceptor proxy is effectively proxyable even if the actual instance is not
Cons:
- Annotations are taken purely from the interface (e.g. what you add via configurator) and can only affect interface provided methods; none of those added by implementation will be intercepted. (requires docs)
- This behaviour is not fully aligned with what standard IF does, for instance placing interceptor binding on a class level will behave differently
The idea is to try and switch to this other approach unless we encounter some blocker. If this proves viable (read "works"), then we should proceed by creating a CDI spec issue with suggested spec changed, much like the suggestion in this comment plus the removal of non-portable behaviour notion. |