[JAVA] Memorandum zur Spring-Integration ~ Grundlegendes zur Spring-Integration Beispiel 3. Enricher ~

Zweck

Um die Spring-Integration zu lernen, habe ich das vom Spring-Projekt bereitgestellte Beispiel verstanden und neu implementiert + arrangiert. Dieser Artikel ist ein Memorandum. Ich denke, es gibt verschiedene Fehler, aber ich würde es begrüßen, wenn Sie auf diesen Punkt hinweisen könnten. Das Beispiel ist im folgenden Git registriert. spring-integration-sample

Diesmal über grundlegende _ ** Enricher ** _. Weiter von JMS Gateway dachte ich, ich könnte es mit dem aggregator von JMS tun, aber bevor ich das Adapter-System wie JMS mache Als ich darüber nachdachte, eine typische Komponente zu erstellen, war dieses Beispielprogramm nicht nur ein reichhaltigeres, sondern es schien mit dem üblichen "Gateway" -Tag grundlegend zu sein, also entschied ich mich, dies zuerst zu tun. Die Version von Spring Integration ist übrigens "4.3.10.RELEASE".

Überblick

Das Konzept von Enricher ist einfach: Fügen Sie dem Nachrichtenkopf oder der Nutzlast unterwegs einige Informationen hinzu. Da die Beispiel-App nur Informationen zur Nutzlast hinzufügt, habe ich versucht, etwas zu implementieren, das dem Header Informationen hinzufügt.

Der Ablauf der Anwendung ist wie folgt. AP-Start-> Geben Sie eine der 1 bis 3 in die Konsole ein und drücken Sie die Eingabetaste (AP-Stopp bei "q") -> 1 bis 4 geben unterschiedliche Informationen aus. Geben Sie das angegebene Ergebnis an die Konsole aus. 1 bis 4 sind wie folgt.

  1. Geben Sie einen Wert in das Benutzerobjekt Payload ein und zeigen Sie ihn an. 2.1 Payload ist jetzt User.username
  2. Fügen Sie der Payload Map Elemente hinzu und zeigen Sie sie an.
  3. Fügen Sie Haeder Attribute hinzu und zeigen Sie sie an.

Implementierung

Gesamtbild

Der Gesamtfluss sieht wie folgt aus.

requestchannel(gateway) -> finduserenricherchannel -> serviceactivator -> finduserservicechannel -> replychannel(gateway) ->Standardausgabe(Ausgabewert in der Hauptklasse)

Zuerst `getBean``` die Service-Schnittstelle, die durch das` Gateway-Tag in der Main-Klasse definiert ist. Anschließend wird die aufzurufende Methode entsprechend dem Eingabewert von der Konsole geändert. Die Verknüpfung mit der aufgerufenen Methode erfolgt mit dem Tag `` `gateway und`` <int: entsprechend dem durch den Wert des Tags ``<int: method>`` angegebenen Kanalnamen. Es ist ein Ablauf der Delegierung der Verarbeitung an das enricher> -Tag `` <int: service-activator>` ``.

messagechannel -> headerenricher -> pollablechannel ->Standardausgabe(Ausgabewert in der Hauptklasse)

HeaderEnricher wusste nicht, wie man es mit dem `` gateway``` -Tag implementiert, also in der Hauptklasse `getBean``` den Sendekanal bzw. den Empfangskanal und senden und empfangen. Es ist die grundlegendste Implementierung, um den Wert abzurufen.

Bean-Definitionsdatei

Die Struktur des Beispielprogramms besteht aus drei Teilen (gateway, enricher, service-activator), aber da es für Qiita schwierig ist, wenn die Bean-Definition lang ist, wurde service-activator dieses Mal mit Anmerkungen implementiert. 1 ist ein Komponentenscan für diesen Service-Aktivator. 2 ist die Bean-Definition des Kanals, der an jeden enricher gesendet werden soll, wenn der Prozess mit gateway geroutet wird. 3 ist die Einstellung von gateway, interface wird durch `` `service-interface``` definiert, und das untergeordnete Element definiert, dass der zu sendende Kanal für jede Methode geändert wird.

    <!-- 1 -->
    <context:component-scan base-package="org.ek.sample"/>
    
    <!-- 2 -->
    <int:channel id="findUserEnricherChannel"/>
    <int:channel id="findUserByUsernameEnricherChannel"/>
    <int:channel id="findUserWithMapEnricherChannel"/>
    <int:channel id="tryHeaderEnricherChannel"/>
    <int:channel id="requestChannel"/>
    <int:channel id="replyChannel"/>
         
	<!-- 3 -->
	<int:gateway id="gateway"
		default-request-timeout="5000"
		default-reply-timeout="5000"
		default-request-channel="requestChannel"
		default-reply-channel="replyChannel"
		service-interface="org.ek.sample.service.UserService">
		<int:method name="findUser"                  request-channel="findUserEnricherChannel"/>
        <int:method name="findUserByUsername"        request-channel="findUserByUsernameEnricherChannel"/>
        <int:method name="findUserWithUsernameInMap" request-channel="findUserWithMapEnricherChannel"/>
    </int:gateway>

In 4 bedeutet dies, dass die Verarbeitung der Methode (`service-activator```) anvertraut wird, die den Kanal des Attributs` request-channel eingibt. Unter den Methoden, die im Attribut `` `service-interface des Tags`` gateway``` angegeben sind, hat die von hier zu delegierende Methode das Argument ``org.ek.sample.domain.User. Da es sich um eine Bean-Datei mit dem Namen `` handelt und keine anderen Attributeinstellungen vorhanden sind, muss _serviceActivator_ die Methode entsprechend definieren. Als nächstes repräsentiert das untergeordnete Element `` <int: property>` den Typ, der zurückgegeben werden soll, org.ek.sample.domain.User```, von dem E-Mail und Passwort Dies bedeutet, dass nur das Attribut den Inhalt von enricher übernimmt. Mit anderen Worten, in dieser Einstellung wird unabhängig davon, wie viele andere Elemente mit enricher bearbeitet werden, dies nicht in dem zu antwortenden Wert wiedergegeben.

    <int:channel id="findUserServiceChannel"/>
    <int:channel id="findUserByUsernameServiceChannel"/>

    <!-- 4 -->
    <int:enricher id="findUserEnricher"
                  input-channel="findUserEnricherChannel"
                  request-channel="findUserServiceChannel">
        <int:property name="email" expression="payload.email"/>
        <int:property name="password" expression="payload.password"/>
    </int:enricher>

    <!-- 5 -->
    <int:enricher id="findUserByUsernameEnricher"
                  input-channel="findUserByUsernameEnricherChannel"
                  request-channel="findUserByUsernameServiceChannel"
                  request-payload-expression="payload.username">
        <int:property name="email" expression="payload.email"/>
        <int:property name="password" expression="payload.password"/>
    </int:enricher>

    <!-- 6 -->
    <int:enricher id="findUserWithMapEnricher"
                  input-channel="findUserWithMapEnricherChannel"
                  request-channel="findUserByUsernameServiceChannel"
                  request-payload-expression="payload.username">
        <int:property name="user" expression="payload"/>
    </int:enricher>
    
    <int:channel id="tryHeaderEnricherPollarChannel" >
    	<int:queue capacity="10"/>
    </int:channel>
    
    <!-- 7 -->
    <int:header-enricher id="tryHeaderEnricher" 
    					input-channel="tryHeaderEnricherChannel" 
    					output-channel="tryHeaderEnricherPollarChannel">    			
    					<int:header name="headerTest" value="test" />		
    					<int:header name="addedHeader" ref="stringConv" method="upperCase" />
    </int:header-enricher>
    <bean id="stringConv" class="org.ek.sample.domain.StringConverter"/>

5 ist fast dasselbe wie 4, aber der einzige Unterschied besteht darin, dass <request-payload-expression> gesetzt ist. Die von diesem enricher angegebene Methode von serviceActivator hat das Argument String. Hier bedeutet dies, dass das Element mit dem Namen username von payload als Argument mit serviceActivator verknüpft ist.

Auch 6 scheint auf den ersten Blick mit 5 identisch zu sein, aber in 6 ist es die Wurzel, wenn die Methode mit dem Argument Map in `` `service-interface``` aufgerufen wird, und hier im Gegensatz zu 5, Map Wenn in key ein Element mit dem Namen Benutzername vorhanden ist, bedeutet dies, dass es mit dem Argument der Methode (wie 5) von serviceActivator verknüpft ist.

7 ist headerEnricher, das MessageHeaders zwei Attribute gibt, die vom einfachen `` input_channel``` übergeben wurden, und das zweite verwendet eine Bean-Dateireferenz (ref). Ausgedrückt. Ich habe eine einfache Klasse erstellt, die nur die referenzierte Klasse mit den großgeschriebenen Argumenten zurückgibt.

service-interface Dies ist die Schnittstelle, die durch das `` `Gateway``` -Tag definiert ist.

public interface UserService {
	
	User findUser(User user);
	
	User findUserByUsername(User user);
	
	Map<String, Object> findUserWithUsernameInMap(Map<String, Object> userdata);

}

serviceActivator Tatsächlich ist die Enricher-Rollenklasse als serviceActivator definiert. Wie in XML erwähnt, hat die erste Methode den Argumenttyp " org.ek.sample.domain.User``" und die zweite Methode den Argumenttyp "String". ..

@MessageEndpoint
@EnableIntegration
public class UserServiceEnricher {
	
	private static final Logger LOGGER = Logger.getLogger(UserServiceEnricher.class);
	
	@ServiceActivator(inputChannel="findUserServiceChannel")
	public User findUser(User user) {

		LOGGER.info(String.format("Calling method 'findUser' with parameter %s", user));
		return new User(user.getUsername() + "-test",//Die durch den Benutzernamen hinzugefügte Zeichenfolge wird nicht wiedergegeben
				   "secret",
				   user.getUsername() + "@springintegration.org");
	}



	@ServiceActivator(inputChannel="findUserByUsernameServiceChannel")
	public User findUserByUsername(String username) {

		LOGGER.info(String.format("Calling method 'findUserByUsername' with parameter: %s", username));

		return new User(username, "secret", username + "@springintegration.org");

	}

Hauptklasse

Ich werde die anderen Teile als die wichtigen weglassen, aber sie sind wie folgt.

	User user = new User();

			if ("1".equals(input)) {

				final User fullUser = service.findUser(user);
				printUserInformation(fullUser);

			} else if ("2".equals(input)) {

				final User fullUser = service.findUserByUsername(user);
				printUserInformation(fullUser);

			} else if ("3".equals(input)) {

                // 3
				final Map<String, Object> userData = new HashMap<String, Object>();
				userData.put("username", "foo_map");
				userData.put("username2", "bar_map");
				final Map<String, Object> enrichedUserData = service.findUserWithUsernameInMap(userData);
				printUserFullInformation(enrichedUserData);

			} else if("4".equals(input)){
              // 4
				MessageChannel mc = context.getBean("tryHeaderEnricherChannel", MessageChannel.class);
				PollableChannel pc = context.getBean("tryHeaderEnricherPollarChannel", PollableChannel.class);
				mc.send(new GenericMessage<String>("foo.bar"));
				printHeaderInfo(pc.receive().getHeaders());				
				
			} else{			
				LOGGER.info("\n\n    Please enter '1', '2', or '3' <enter>:\n\n");
			}	
            
            
            
            // omitted
            
            
                // 5
            	private static void printUserFullInformation(Map<String, Object> userdataMap) {
		for(Map.Entry<String, Object> entry : userdataMap.entrySet()) {
			Object val = entry.getValue();
			if(val instanceof User) {
				User user = (User) entry.getValue();
				LOGGER.info(String.format("\n\n    User found - Key of Map: '%s',  Username: '%s',  Email: '%s', Password: '%s'.\n\n",
						entry.getKey(), user.getUsername(), user.getEmail(), user.getPassword()));
			}else {
				LOGGER.info(String.format("\n\n    User found - Key of Map: '%s',  Username: '%s',  Email: '%s', Password: '%s'.\n\n",
						entry.getKey(), val, null, null));
			}
		}
	}
    
    // 6
    private static void printHeaderInfo(MessageHeaders mh) {
		LOGGER.info("\n\n    " + "headerTest :" + mh.get("headerTest") + ", addedHeader :" + mh.get("addedHeader"));
	}

Der Teil 3 wird geringfügig geändert, und die Schlüsselwerte Benutzername und Benutzername2 werden in das Argument Map eingefügt, um daraus ein Argument zu machen. Außerdem werden alle Rückgabewerte mit _map.entrySet () _ (5) angezeigt. Wie das folgende Ergebnis zeigt, handelt es sich anscheinend um ein Element, das mit dem im Argument + enricher angegebenen Map-Element erstellt wurde. Gibt es. Der Schlüsselname wird in XML durch `<int: property>` benutzerdefiniert. Da im Wertattribut in xml Nutzdaten angegeben wurden, wird das Benutzerobjekt zum Wert von Map, wie es ist.

0:10:42.631 INFO  [main][org.ek.sample.Main] 

    User found - Key of Map: 'username2',  Username: 'bar_map',  Email: 'null', Password: 'null'.


00:10:42.632 INFO  [main][org.ek.sample.Main] 

    User found - Key of Map: 'user',  Username: 'foo_map',  Email: 'secret', Password: '[email protected]'.


00:10:42.633 INFO  [main][org.ek.sample.Main] 

    User found - Key of Map: 'username',  Username: 'foo_map',  Email: 'null', Password: 'null'.

4 ist headerEnricher, und wenn Sie MessageHeader gemäß der Methode abrufen, werden dem Header Attribute hinzugefügt, wie in XML angegeben. Der Grund, warum nur der Header so implementiert wird, ist, dass, wie oben erwähnt, die Standardeinstellung des Gateways die Rückgabe von Nutzdaten ist, sodass es nicht möglich war, den Wert des Headers zu ermitteln und die Nutzdaten zu verbessern. Dies allein scheint jedoch umständlich zu sein, und ich dachte, ich könnte den Header irgendwie so einstellen, dass er mit dem "Gateway" -Tag angereichert wird, aber ich werde es untersuchen, wenn ich Zeit habe. Das Folgende ist das Anzeigeergebnis von 6.

00:16:42.883 INFO  [main][org.ek.sample.Main] 

    headerTest :test, addedHeader :FOO.BAR

Dieses Mal habe ich zum ersten Mal das `` `Gateway``` Tag verwendet, das kein Adapter ist, also hatte ich das Gefühl, die Grundlagen der Integration irgendwie verstanden zu haben. Übrigens, in welcher Reihenfolge sollten die Proben implementiert werden, um die Federintegration effektiv zu lernen?

Der diesmal implementierte Code lautet wie folgt. Optimiertes Beispiel

Recommended Posts

Memorandum zur Spring-Integration ~ Grundlegendes zur Spring-Integration Beispiel 3. Enricher ~
Memorandum zur Spring-Integrationsstudie ~ Beispiel für Spring-Integration verstehen 1. Hallo Welt ~
Memorandum zur Spring-Integration ~ Grundlegendes zur Spring-Integration Beispiel 2. JMS-Gateway ~
WebMvcConfigurer-Memorandum von Spring Boot 2.0 (Spring 5)
Java-Studienmemorandum
Spring Boot Denken Sie daran
Memorandum (Spring Web)
Memorandum zur Javasilver-Studiensitzung