API to chain Decorators programmatically?
by Ondrej Mihályi
I think that Decorators are a great concept in CDI, but it cannot provide
solution to a wide variety of problems where the general decorator pattern
makes sense.
AFAIK, it is not possible to chain decorators at runtime, in order to reuse
the decorator mechanism to solve class explosion problem and create a
flexible architecture, similar to what java.io API provides with chained
input/output streams (subclasses of java.io.InputStream
<http://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html>).
I think it would make sense to be able to apply decorators to a bean at
runtime.
What do you think about extending *Instance* class by adding a method like*
Instance<T> decorateWith(Class<?> c)* as in the following example?
@Inject
Instance<DecoratedInterface> instance;
...
DecoratedInterface decorated =
instance.*decorateWith(Decorator1.class)*
.decorateWith(Decorator2.class)
.get();
I haven't find a way to do something similar using the current API, nor did
I find any third-party CDI extension to provide something similar.
Ondrej
8 years, 6 months
[JBoss JIRA] (CDI-552) Add support for injection, decorators and interceptors on "new-ed" objects
by Ondrej Mihályi (JIRA)
[ https://issues.jboss.org/browse/CDI-552?page=com.atlassian.jira.plugin.sy... ]
Ondrej Mihályi commented on CDI-552:
------------------------------------
Isn't this what DeltaSpike provides already with {{BeanProvider.injectFields(myObject)}}? https://deltaspike.apache.org/documentation/core.html#_beanprovider
This method clearly only injects the dependencies, it does not invoke any lifecycle methods and does not add the object to any scope.
It would be useful to make this into the CDI spec, such as {{CDI.current().injectDependencies(Object o)}}.
It might also make sense to execute the lifecycle methods by {{CDI.current().invokePostConstruct(Object o)}} and {{invokePreDestroy(Object o}}, although they may be executed as directly on the object.
> Add support for injection, decorators and interceptors on "new-ed" objects
> --------------------------------------------------------------------------
>
> Key: CDI-552
> URL: https://issues.jboss.org/browse/CDI-552
> Project: CDI Specification Issues
> Issue Type: Feature Request
> Components: Beans, Decorators, Interceptors, Resolution
> Affects Versions: 2.0-EDR1
> Reporter: Rogerio Liesenfeld
>
> The current CDI programming model is not friendly to object-oriented code or proper class design, and does not support true POJOs.
> With this I mean:
> 1) For object-oriented code, I need to be able to instantiate and use *stateful*, short-lived, objects, while still having @Inject fields in it. I shouldn't be forced to have a stateless (non-OO) class (ie, a [Transaction Script|http://martinfowler.com/eaaCatalog/transactionScript.html]).
> 2) Most classes in a business app are not meant to be used as subclasses, ie, they are not designed for extension; therefore, I should be able to make them {{final}} (see http://lcsd05.cs.tamu.edu/slides/keynote.pdf, page 26, or item 17 in the [book|http://www.amazon.com/Effective-Java-2nd-Joshua-Bloch/dp/0321356683]).
> 3) For a class to truly be a POJO, I must be able to make *full use* of the Java language when designing and implementing it; arbitrary constraints like "can't be final", "can't have final instance fields", "cannot be instantiated directly", etc. prevent it from being a "plain-old" Java object.
> Specifically, what I want is to be able to write the following in a JSF/CDI backing bean for a web UI:
> {code}
> MyBusinessService businessOp = new MyBusinessService(fieldFromUI1, fieldFromUI2, listWithMoreDataFromUI);
> businessOp.performSomeBusinessOperation(otherArgs);
> String result1 = businessOp.getResultXyz();
> List<result> moreResultData = businessOp.getFinalData();
> {code}
> ... while having MyBusinessService be a CDI bean containing one or more @Inject/@PersistenceContext fields (typically, an EntityManager and perhaps other service beans).
> Without this ability, application developers are forced to create procedural Transation Scripts (stateless service class, which tend to have low cohesion).
> For a CDI implementation to do this, it will need to use the java.lang.instrument API, like others tools (AspectJ, JBoss AOP, JBoss Byteman, JaCoCo, JMockit) already do.
> Also, for reference, the Spring framework already supports it for some time: http://docs.spring.io/spring/docs/3.0.0.M3/spring-framework-reference/htm...
--
This message was sent by Atlassian JIRA
(v6.4.11#64026)
8 years, 6 months
[JBoss JIRA] (CDI-403) why decorator requires interface
by Ondrej Mihályi (JIRA)
[ https://issues.jboss.org/browse/CDI-403?page=com.atlassian.jira.plugin.sy... ]
Ondrej Mihályi commented on CDI-403:
------------------------------------
I think that it is worth to remove the requirement on interface in CDI2.
It should be fairly easy to specify additional scenario, where the decorator can extend the decorated class => it would inherit all public methods as if all methods would be exposed by an interface, and would decorate all beans injected by their class instead of by interface.
Currently, the way to work around this is to declare such decorator using {{@Specialized}} + {{@Alternative}} and delegating to methods in predecessor. This is confusing in the code, as the decorator pattern is implemented using to other patterns. And it is not the same as delegate to another injected delegate, as multiple decorators cannot be chained:
{code:java}
@Specialized
@Alternative
public class MyBeanDecorator extends MyBean {
@Overrides
public String hello() {
return super.hello() + ", world!"; // decorates by adding ", world!" after result of hello()
}
}
{code}
> why decorator requires interface
> --------------------------------
>
> Key: CDI-403
> URL: https://issues.jboss.org/browse/CDI-403
> Project: CDI Specification Issues
> Issue Type: Clarification
> Reporter: Mathieu Lachance
>
> As discussed with Jozef Hartinger on the WELD forum thread (see forum reference and CDI-224),
> would it be possible to revisit why decorator requires an interface ?
> I do not understand the semantic difference between:
> 1. a decorator to be an abstract class which implements an interface, which delegate to the same interface.
> 2. a decorator to be a concrete class which extends a another class, which delegates to the same class.
> Why 1. should be allowed and why 2. should be disallowed ?
> As stated in CDI-224, if there is no technical reason of disallowing 2., should it be then considerate as a vendor specific feature to support it whether or not ?
> It is kind of sad that only decorators requires an interface while all the others Java EE 6 features do not.
> Thanks,
--
This message was sent by Atlassian JIRA
(v6.4.11#64026)
8 years, 6 months
[JBoss JIRA] (CDI-608) Fix generics used within addObserverMethod
by Martin Kouba (JIRA)
[ https://issues.jboss.org/browse/CDI-608?page=com.atlassian.jira.plugin.sy... ]
Martin Kouba commented on CDI-608:
----------------------------------
I'm not sure. But we need the complete information to simulate the problem.
> Fix generics used within addObserverMethod
> ------------------------------------------
>
> Key: CDI-608
> URL: https://issues.jboss.org/browse/CDI-608
> Project: CDI Specification Issues
> Issue Type: Feature Request
> Reporter: John Ament
>
> the following code doesn’t compile:
> {code}
> cdiEventEndpoints.values().stream().forEach(endpoint -> abd.addObserverMethod()
> .beanClass(CdiEventComponent.class)
> .observedType(endpoint.getType())
> .qualifiers(endpoint.getQualifiers())
> .notifyWith(endpoint::notify);
> {code}
> I need to write:
> {code}
> cdiEventEndpoints.values().stream().forEach(endpoint -> addCdiEventObserver(abd, endpoint));
> private <T> void addCdiEventObserver(AfterBeanDiscovery abd, CdiEventEndpoint<T> endpoint) {
> abd.<T>addObserverMethod()
> .beanClass(CdiEventComponent.class)
> .observedType(endpoint.getType())
> .qualifiers(endpoint.getQualifiers())
> .notifyWith(endpoint::notify);
> }
> {code}
--
This message was sent by Atlassian JIRA
(v6.4.11#64026)
8 years, 7 months
[JBoss JIRA] (CDI-608) Fix generics used within addObserverMethod
by John Ament (JIRA)
[ https://issues.jboss.org/browse/CDI-608?page=com.atlassian.jira.plugin.sy... ]
John Ament commented on CDI-608:
--------------------------------
Not sure, what type does it need to be to support this?
> Fix generics used within addObserverMethod
> ------------------------------------------
>
> Key: CDI-608
> URL: https://issues.jboss.org/browse/CDI-608
> Project: CDI Specification Issues
> Issue Type: Feature Request
> Reporter: John Ament
>
> the following code doesn’t compile:
> {code}
> cdiEventEndpoints.values().stream().forEach(endpoint -> abd.addObserverMethod()
> .beanClass(CdiEventComponent.class)
> .observedType(endpoint.getType())
> .qualifiers(endpoint.getQualifiers())
> .notifyWith(endpoint::notify);
> {code}
> I need to write:
> {code}
> cdiEventEndpoints.values().stream().forEach(endpoint -> addCdiEventObserver(abd, endpoint));
> private <T> void addCdiEventObserver(AfterBeanDiscovery abd, CdiEventEndpoint<T> endpoint) {
> abd.<T>addObserverMethod()
> .beanClass(CdiEventComponent.class)
> .observedType(endpoint.getType())
> .qualifiers(endpoint.getQualifiers())
> .notifyWith(endpoint::notify);
> }
> {code}
--
This message was sent by Atlassian JIRA
(v6.4.11#64026)
8 years, 7 months
[JBoss JIRA] (CDI-609) Clarify behaviour of ObserverMethodConfigurator<T> read
by Tomas Remes (JIRA)
[ https://issues.jboss.org/browse/CDI-609?page=com.atlassian.jira.plugin.sy... ]
Tomas Remes commented on CDI-609:
---------------------------------
While I am implementing TCK tests I am starting to dislike those read methods at all TBH. They appear to me as a nasty workaround (I don't like the fact that when I want to create fresh new observer method I need to read some existing. It doesn't really make sense to me) . I would really rather go with something like https://github.com/tremes/cdi/commit/6ebc86ad3fdd34a491c53dc90628fbfecbae.... It's much cleaner IMHO - just allow configuration (like qualifiers, reception, isAsync etc.) within {{ProcessObserverMethod}} but things like setting observedType and beanClass allow only within {{AfterBeanDiscovery}} when you really want to add new observer method. With this you can do https://gist.github.com/tremes/84c825a62cd3392c124814d036ee1239.
> Clarify behaviour of ObserverMethodConfigurator<T> read
> -------------------------------------------------------
>
> Key: CDI-609
> URL: https://issues.jboss.org/browse/CDI-609
> Project: CDI Specification Issues
> Issue Type: Clarification
> Affects Versions: 2.0-EDR2
> Reporter: Tomas Remes
>
> It's not clear what should happen in case if you are using ObserverMethodConfigurator and attempting to read from a method ({{Method}}, {{AnnotatedMethod}}) which doesn't have any parameter annotated @Observes. E.g something like this in ABD lifecycle event ("observesMelon" doesn't have any @Observes):
> {code}
> Method melonMethod = FruitObserver.class.getMethod("observesMelon", Melon.class);
> abd.addObserverMethod().read(melonMethod)
> {code}
--
This message was sent by Atlassian JIRA
(v6.4.11#64026)
8 years, 7 months
[JBoss JIRA] (CDI-608) Fix generics used within addObserverMethod
by Martin Kouba (JIRA)
[ https://issues.jboss.org/browse/CDI-608?page=com.atlassian.jira.plugin.sy... ]
Martin Kouba commented on CDI-608:
----------------------------------
What's the type of {{cdiEventEndpoints}}?
> Fix generics used within addObserverMethod
> ------------------------------------------
>
> Key: CDI-608
> URL: https://issues.jboss.org/browse/CDI-608
> Project: CDI Specification Issues
> Issue Type: Feature Request
> Reporter: John Ament
>
> the following code doesn’t compile:
> {code}
> cdiEventEndpoints.values().stream().forEach(endpoint -> abd.addObserverMethod()
> .beanClass(CdiEventComponent.class)
> .observedType(endpoint.getType())
> .qualifiers(endpoint.getQualifiers())
> .notifyWith(endpoint::notify);
> {code}
> I need to write:
> {code}
> cdiEventEndpoints.values().stream().forEach(endpoint -> addCdiEventObserver(abd, endpoint));
> private <T> void addCdiEventObserver(AfterBeanDiscovery abd, CdiEventEndpoint<T> endpoint) {
> abd.<T>addObserverMethod()
> .beanClass(CdiEventComponent.class)
> .observedType(endpoint.getType())
> .qualifiers(endpoint.getQualifiers())
> .notifyWith(endpoint::notify);
> }
> {code}
--
This message was sent by Atlassian JIRA
(v6.4.11#64026)
8 years, 7 months
[JBoss JIRA] (CDI-609) Clarify behaviour of ObserverMethodConfigurator<T> read
by Martin Kouba (JIRA)
[ https://issues.jboss.org/browse/CDI-609?page=com.atlassian.jira.plugin.sy... ]
Martin Kouba commented on CDI-609:
----------------------------------
I think we should probably throw an {{IllegalArgumentException}} - this is what we're going to implement as a part of WELD-2159.
> Clarify behaviour of ObserverMethodConfigurator<T> read
> -------------------------------------------------------
>
> Key: CDI-609
> URL: https://issues.jboss.org/browse/CDI-609
> Project: CDI Specification Issues
> Issue Type: Clarification
> Affects Versions: 2.0-EDR2
> Reporter: Tomas Remes
>
> It's not clear what should happen in case if you are using ObserverMethodConfigurator and attempting to read from a method ({{Method}}, {{AnnotatedMethod}}) which doesn't have any parameter annotated @Observes. E.g something like this in ABD lifecycle event ("observesMelon" doesn't have any @Observes):
> {code}
> Method melonMethod = FruitObserver.class.getMethod("observesMelon", Melon.class);
> abd.addObserverMethod().read(melonMethod)
> {code}
--
This message was sent by Atlassian JIRA
(v6.4.11#64026)
8 years, 7 months
[JBoss JIRA] (CDI-609) Clarify behaviour of ObserverMethodConfigurator<T> read
by Tomas Remes (JIRA)
Tomas Remes created CDI-609:
-------------------------------
Summary: Clarify behaviour of ObserverMethodConfigurator<T> read
Key: CDI-609
URL: https://issues.jboss.org/browse/CDI-609
Project: CDI Specification Issues
Issue Type: Clarification
Affects Versions: 2.0-EDR2
Reporter: Tomas Remes
It's not clear what should happen in case if you are using ObserverMethodConfigurator and attempting to read from a method ({{Method}}, {{AnnotatedMethod}}) which doesn't have any parameter annotated @Observes. E.g something like this in ABD lifecycle event ("observesMelon" doesn't have any @Observes):
{code}
Method melonMethod = FruitObserver.class.getMethod("observesMelon", Melon.class);
abd.addObserverMethod().read(melonMethod)
{code}
--
This message was sent by Atlassian JIRA
(v6.4.11#64026)
8 years, 7 months
[JBoss JIRA] (CDI-608) Fix generics used within addObserverMethod
by John Ament (JIRA)
John Ament created CDI-608:
------------------------------
Summary: Fix generics used within addObserverMethod
Key: CDI-608
URL: https://issues.jboss.org/browse/CDI-608
Project: CDI Specification Issues
Issue Type: Feature Request
Reporter: John Ament
the following code doesn’t compile:
{code}
cdiEventEndpoints.values().stream().forEach(endpoint -> abd.addObserverMethod()
.beanClass(CdiEventComponent.class)
.observedType(endpoint.getType())
.qualifiers(endpoint.getQualifiers())
.notifyWith(endpoint::notify);
{code}
I need to write:
{code}
cdiEventEndpoints.values().stream().forEach(endpoint -> addCdiEventObserver(abd, endpoint));
private <T> void addCdiEventObserver(AfterBeanDiscovery abd, CdiEventEndpoint<T> endpoint) {
abd.<T>addObserverMethod()
.beanClass(CdiEventComponent.class)
.observedType(endpoint.getType())
.qualifiers(endpoint.getQualifiers())
.notifyWith(endpoint::notify);
}
{code}
--
This message was sent by Atlassian JIRA
(v6.4.11#64026)
8 years, 7 months