[
https://issues.apache.org/jira/browse/PIVOT-535?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12880664#action_12880664
]
Appddevvv commented on PIVOT-535:
---------------------------------
I've attached a design spec below. The posted code is a starting point but not
a final answer. More thinking is needed around automatic unsubscribing. The
issue of unsubscribing can be mostly handled using weak listeners *inside* the
proposed general purpose message listener class. Weak listeners are safe inside
the proposed message listener class associated with the annotation but robust
thinking and examples will help flush out all use cases. They are safe as
proposed but you can do without them with a little bit more code, they were an
easy answer to the unsubscription problem to get a first cut out.
Pivot team, if you decide to keep this open, its okay if this gets bumped down
on the priority list. I'll update the starting points that I sent out and post
them.
Here's the spec:
Design Intent: To reduce code and improve line-of-sight into client intent
when registering for application context messages in java. The motivation was
based on the dev's list recommendation to look at pivot's message management
capabilities and potentially use them, if appropriate, for decoupling sender
and receivers. This was in response to some comments about EventBus somewhere
in early 2010. The intent to make this easier in java is the same as allowing
listener registration in the serializer in script. In some cases, its
significantly easier and cleaner.
Examples:
Change code like this:
public class MyClass ... {
....
ApplicationContext.subscribe(MyTopic.class, new
ApplicationContextMessageListener<MyTopic>() {
@Override
public void sentMessage(MyTopic arg) {
....
justDoIt(arg);
...
}
public void justDoIt(MyTopic arg) {
....
}
} ;
to:
public class MyClass ... {
public MyClass() {
MessageListenerAnnotationProcessor.process(this);
}
@MessageListener
public void justDoit(MyTopic arg) {
...
}
}
If you have more than one topic you are subscribing to within a class, the
intent becomes more clear within that class. If you subclass the serializer,
you can process this annotation on any object transparently but otherwise the
annotation processor has to be called to scan the class. In the above example,
it is shown being used in the constructor.
Design points:
a) Allow listener registration using annotations on a method.
b) Allow the option of strong or weak subscription. This refers to the proposed
general message listener and *not* within the ApplicationContext itself.
Default is weak. Most importantly, weak listener bad behavior is completely
managed so it is less of an issue than with using inner anonymous classes.
That's a plus. Also, strong references are not always perfect if you forget to
unsubscribe. Both strong and weak have beneficial use cases and the code is
nearly identical. Note that in the current form, you need to use a weak
reference to the target object to allow it to unregister itself but that's
because the starting point code examples were written quickly.
c) Allow the specification of the listener type when the annotation is
processed. This allows you to create your own listener and move additional
filtering and conditional logic out of your class and into the message handler.
This makes it easier to address filtering. Class-level filtering can be fairly
large-grained. In addition, it allows transparent add-ons and extensions to be
added that are outside the scope of pivot's focus such as message logging,
interception, filtering, queue control and proxying. This also allows other
instantiation and initialization methods to be employed.
d) Support minimal reply-request behavior. This is also a common use of
messages and the code is identical except for 2 lines in the implementation.
This allows the user to write a method like below and translate messages
without further reference to the application context. In fact, there are no
references to the application context, message listeners or other pivot
elements.
public class MyClass ... {
@MessageListener(requestReply=true)
public OutputMessage process(InputMessage message) {
....
return outputMessage;
}
}
Alternatives:
a) Perform message listening in script. This reduces code and in some cases,
improves clarity on intent. However, this is not a java based solution and some
classes may not have the benefit of being created in the serializer.
b) Keep coding by hand with anonymous classes. This approach works and is fine
but part of the recommendation is to make this easier and more clear.
c) Use other libraries like EventBus. This is a good option, but the idea was
to use more pivot features and decrease external library dependence, where
possible. EventBus has more fine-grained filtering behavior but this may or may
not be critical to a pivot application. For simple uses, pivot's is fine and
appropriate. Easier message registration is a plus. The two systems can be
easily bridged if need be.
Pros:
a) Clearer client intent.
b) Less java coding. This is similar in concept to the benefits of using of
script in the serializer.
Cons:
a) More code in the pivot base to maintain.
b) Uses reflection (all internally). Some think this should be avoided in
general.
c) Without ApplicationContext enhancements, you need to use weak listeners
inside the specialized message listener class. While the implementation would
be safe, it requires dealing with weak listener perceptions.
d) If you only have 1-2 message listener classes in your application, this is
not reducing alot of complexity.
> Add a @MessageListener annotation and an annotation processor for application
> context message listener
> ------------------------------------------------------------------------------------------------------
>
> Key: PIVOT-535
> URL: https://issues.apache.org/jira/browse/PIVOT-535
> Project: Pivot
> Issue Type: Improvement
> Reporter: Appddevvv
>
> Add a message listener annotation and a static method for annotation
> processing to automatically enroll instance/methods in application message
> handling.
> I have the classes that I can submit as a starting point. They allow weak and
> strong references as well as optional request-reply semantics.
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.