Recently in the work will be used to spring cloud stream, online Chinese information almost no, read the official website configuration, not easy to finish, here to share the use of the process, but also to make a record.
Home page You use the scene is to achieve communication between the two apps, the first app output data, the second app input data. The app here means a service.
1. Binding in a configuration file
APP1, configure output channel related information.
Application.yml or Application.properties or configuration files, configuring
Spring:
Cloud:
stream:
bindings:
output_channel: #channelName
destination:mydest # Destination, or can be considered a release-subscription model inside the topic
binder:rabbit1
binders:
rabbit1:
type:rabbit
Environment:
Spring:
rabbitmq:
host:192.168.1.1 #rabbitMQ服务器地址
port:5672 # RABBITMQ Server Port
username:username
password:pwd
virtual-host:/hostname
In APP2, configure input channel related information.
Spring:
Cloud:
stream:
bindings:
input_channel: #<span style= "font-family:arial, Helvetica, Sans-serif; " >position1. </span><span style= "font-family:arial, Helvetica, Sans-serif;" >channelName.</span>
destination:modest #position2. Destination, or the topic in the Publish-subscribe model, should be consistent with the topic published in the output app, which means subscribing to the topic
binder:rabbit1
binders:
rabbit1:
type:rabbit #可以是其它, such as Kafka
Environment:
Spring:
rabbitmq:
host:192.168.1.1 #rabbitMQ服务器地址
port:5672 #rabbitMQ服务器端口
username:username
password:pwd
virtual-host:/ HostName
2. Define the interface for channel binding:
The official website example, uses is the sink and the source interface, if each app has only one channel, may directly use the stream to bring the interface, but if wants to implement many interfaces, needs to carry on the interface definition. The following is an example of my own definition of the interface, which is described in detail in the comments.
Import Org.springframework.cloud.stream.annotation.Input;
Import Org.springframework.cloud.stream.annotation.Output;
Import Org.springframework.messaging.MessageChannel;
Import Org.springframework.messaging.SubscribableChannel; Public interface Barista {String Input_channel = "Input_channel"; #position3 String output<span style= "font-family:arial, Helvetica, Sans-serif;"
>_CHANNEL</span> = "Output_channel";
String INPUT1 = "INPUT1";
String OUTPUT1 = "OUTPUT1"; #注解 @Input declared it to be an input type of channel, the name is <span style= "font-family:arial, Helvetica, Sans-serif;" >barista</span><span style= "font-family:arial, Helvetica, Sans-serif;" ". Input_channel, the Input_channel of Position3. This name should be consistent with the configuration file in the configuration app2 above, indicating that a channel named Input_channel was injected with a type of input, and that the subject of the subscription was the mydest of the Position2 statement </span > @Input (<span style= "font-family:arial, Helvetica, Sans-serif;" >barista</span><span style= "font-family:arial, Helvetica, Sans-serif;" ". Input_chanNel</span><span style= "font-family:arial, Helvetica, Sans-serif;"
>) </span> subscribablechannel loginput (); # annotation @output declares that it is an output type of channel, the name is <span style= "font-family:arial, Helvetica, Sans-serif;" >output_channel. This name is consistent with the channel name in App1, indicating that a channel with the name Output_channel is injected, the type is output, and the subject name of the publication is mydest. </span> @Output (Barista.<span style= "font-family:arial, Helvetica, Sans-serif;" >output</span><span style= "font-family:arial, Helvetica, Sans-serif;" >_channel</span><span style= "font-family:arial, Helvetica, Sans-serif;"
>) </span> messagechannel logoutput ();
@Input (BARISTA.INPUT1) Subscribablechannel input1 ();
@Output (BARISTA.OUTPUT1) Messagechannel output1 (); }
The barista interface here is defined as a parameter to the following class, which defines the channel type and the channel name.
The channel name is used as a configuration, and the channel type determines whether the app uses the channel to send messages or receive messages from it.
3. Inject the above barista interface into the Application.java class of the output application
import Barista; import org.springframework.boot.SpringApplication; import
Org.springframework.boot.autoconfigure.SpringBootApplication;
Import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
Import org.springframework.cloud.netflix.feign.EnableFeignClients;
Import org.springframework.cloud.stream.annotation.EnableBinding;
Import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; /** * * */@SpringBootApplication @EnableDiscoveryClient @EnableFeignClients @EnableRedisHttpSession @EnableBinding ( Barista.class) public class Outputserviceapplication {public static void main (string[] args) {Springapplicat Ion.run (<span style= "font-family:arial, Helvetica, Sans-serif;" >outputserviceapplication</span><span style= "font-family:arial, Helvetica, Sans-serif;" >.class, args);</span>}}
There is a need to inject an interface into the application class, otherwise you will be prompted to not find the bean when referencing the interface. The reason is that the stream will automatically create an instance of the parameter Barista.class only if the @enablebinding annotation is found. This is a spring cloud stream with its own operation that needs to be adhered to.
4. Send message:
Import Barista;
Import Org.apache.commons.logging.Log;
Import org.apache.commons.logging.LogFactory;
Import org.springframework.beans.factory.annotation.Autowired;
Import Org.springframework.messaging.support.MessageBuilder;
Import org.springframework.stereotype.Component;
Import Org.springframework.stereotype.Service;
@Service
@Component Public
class Rabbitsender {
@Autowired
private Barista source;
Send Message public
String SendMessage () {
try{
obj obj = new obj ();
Source.logoutput (). Send (Messagebuilder.withpayload (obj). build ());
Logger.info ("send");
catch (Exception e) {
e.printstacktrace ();
}
return null;
}
}
Source is an instantiated barista object in which the Logoutput () method actually invokes a messagechannel and uses it to send the message out.
5. Receive Message:
Inject the interface into the input application and declare the listener
Import Barista;
Import Org.apache.commons.logging.Log;
Import org.apache.commons.logging.LogFactory;
Import org.springframework.beans.factory.annotation.Autowired;
Import org.springframework.cloud.stream.annotation.EnableBinding;
Import Org.springframework.cloud.stream.annotation.StreamListener;
Import Org.springframework.messaging.Message;
@EnableBinding (barista.class) public
class Rabbitreceiver {
private static final Log logger = Logfactory.getlog (Rabbitreceiver.class);
@StreamListener (barista.log_input) public
void Receiver (message<obj> message) {
obj obj = Message.getpayload ();
Logger.info ("Accepted object:" +<span style= "font-family:arial, Helvetica, Sans-serif;") >obj</span><span style= "font-family:arial, Helvetica, Sans-serif;" >+ "\ n");</span>
}
}
First, add the annotation @enablebinding (Barista.class) on the class to implement the connection to the message agent. The annotation @streamlistener is added to the method receiver (), and the channel name is used as the parameter to monitor the corresponding channel.
So far, two apps have been implemented to deliver messages.