Message Publishing feature will allow you to send a message as a result of method invocation. For example; Imagine you have a component and every time the state of this components changes you would like to get notified. The easiest way to send notification would be to send a message to a dedicated channel, but how would you connect the method invocation that changes the state of the object to a message sending process and what should be the structure of the message? Message Publishing feature will allow you to do just that.
Spring Integration provides two approaches - XML and Annotation.
Annotation bassed approach allows you to annotate any method with @Publisher
annotation and
provide configuration attributes which will dictate the structure of a Message. Invocation of such
method will be proxied through PublisherAnnotationAdvisor
which will
construct a Message and send it to a channel.
Internally PublisherAnnotationAdvisor
uses Spring 3.0 Expression Language support giving you
the flexibility and control over the structure of a Message it will build.
PublisherAnnotationAdvisor
defines and binds the following variables:
#return - will bind to a return value allowing you to reference it or its attributes (e.g., #return.foo where 'foo' is an attribute of the object bound to #return)
#exception - will bind to an exception if one is thrown.
#[parameName] - will be dynamically constructed pointing to the method parameter names (e.g., #fname as in the above method)
@Publisher(value="#return", channel="testChannel", headers="bar='123',fname=#fname") public String setName(String fname, String lname){ return fname + " " + lname; }
In the above example the Message will be constructed and its structure will be as follows:
Message payload - will be of type String and contain the value returned by the method.
Message headers will be 'bar' with value of "123" and 'fname' with value of 'fname' parameter of the method.
As with any other annotation you will need to register PublisherAnnotationBeanPostProcessor
<bean class="org.springframework.integration.aop.PublisherAnnotationBeanPostProcessor"/>
XML-based approach allows you to configure Message Publishing via AOP-based configuration and although configuration itself is a bit more extensive it has certain benefits over annotation based approach since it allows you to use pointcut expressions, thus possibly intercepting multiple methods at once.
To configure Message Publishing via XML you need to provide two things:
Register MessagePublishingInterceptor
Provide AOP configuration to apply MessagePublishingInterceptor
<bean id="testBean" class="org.springframework.integration.aop.MessagePublishingInterceptorUsageTest$TestBean" /> <si:channel id="testChannel"> <si:queue /> </si:channel> <aop:config> <aop:advisor advice-ref="publishingInterceptor" pointcut="bean(testBean)" /> </aop:config> <bean id="publishingInterceptor" class="org.springframework.integration.aop.MessagePublishingInterceptor"> <constructor-arg> <bean class="org.springframework.integration.aop.MethodNameMappingExpressionSource"> <constructor-arg> <map> <entry key="*" value="#return" /> </map> </constructor-arg> <property name="headerExpressionMap"> <map> <entry key="*" value="foo='bar'" /> </map> </property> <property name="channelMap"> <map> <entry key="setName" value="channel" /> </map> </property> </bean> </constructor-arg> <property name="channelResolver"> <bean class="org.springframework.integration.channel.MapBasedChannelResolver"> <property name="channelMap"> <map> <entry key="channel" value-ref="testChannel" /> </map> </property> </bean> </property> </bean>
As you can see MessagePublishingInterceptor
defines and binds the same variables as
PublisherAnnotationAdvisor
to utilize the power of Spring 3.0 Expression Langage.
In this example after execution of any public method of a testBean
a Message
will be constructed with the following structure:
Message payload - will be of type and value returned by an executed method.
Message headers will be 'foo' with value of "bar".
In future versions namespace support will be available to simplify XML-based configuration.