Konventionen für die Java DSL-Personalcodierung, die bei der Erstellung von Apache Camel-Routen verwendet werden

Wenn Sie in Apache Camel eine "Route" erstellen, schreiben Sie diese in Original DSL, das einfach die vorbereiteten Methoden verbindet. Dieses DSL unterstützt auch ** bedingte Verzweigung ** und ** Schleife **.

Wenn Sie jedoch gemäß dem Java-Styleguide schreiben, haben die Methoden, die eine bedingte Verzweigung und eine interne Schleifenverarbeitung erstellen, denselben Einzug, was das Lesen als DSL sehr schwierig macht. Daher wird davon ausgegangen, dass ** es besser ist, den Einzug selbst hinzuzufügen **.

Es gibt auch mehrere Möglichkeiten, andere Teile zu schreiben, aber ich möchte sie auf der Seite vereinheitlichen, die leicht zu lesen ist. Deshalb habe ich die Codierungsstandards zusammengefasst, die ich persönlich festgelegt habe. Es können nur die Funktionen festgelegt werden, die ich verwendet habe. Daher werde ich sie hinzufügen oder ändern, wenn meine Erfahrung in Zukunft zunimmt.

RouteBuilder Über die Form der gesamten Route ist das die Basis. Es wird nur der Inhalt von configure () angezeigt.

from("direct:sample").routeId("MySampleRoute")
		// some process
		.to("mock:aaa").id("SamplePartA")
		.log(LoggingLevel.DEBUG,
				"very long text...")

		// another process
		.to("mock:bbb")
;

Strukturiert

Diejenigen, die bedingte Verzweigungen und Schleifen erzeugen, sind im Grunde genommen "xxx ()" bis "end ()". Die allgemeinen Regeln lauten wie folgt.

choice Entspricht einer switch-Anweisung (break ist nicht erforderlich). Da der bedingte Ausdruck jedoch auf der When-Seite geschrieben ist, sind SQL und die * expressionless case-Anweisung *, die mit Ruby ausgeführt werden kann, besser. Das ist ähnlich.

https://camel.apache.org/components/latest/eips/choice-eip.html

from("direct:sample")
		.choice()
			.when(new MyPredicateA())
				.to("mock:aaa")
			.when(new MyPredicateB())
				.to("mock:bbb")
			.otherwise()
				.to("mock:zzz")
		.end()
;

Geben Sie eine Instanz von "Prädikat" in der Bedingung an. (Dokumentation)

filter Wenn Sie nur einen "when ()" - Zweig haben, sollten Sie "filter ()" anstelle von "choice ()" verwenden. Die Anzahl der Zeilen und Einrückungen wird reduziert, um das Lesen zu erleichtern. Besonders nützlich beim Schreiben von Schutzklauseln.

https://camel.apache.org/components/latest/eips/filter-eip.html

Beispiel einer Schutzklausel


//Ohne Schutzklausel schwer zu lesen (* Dies ist nicht auf Kamel beschränkt)
from("direct:noGuard")
		.choice()
			.when(new MyPredicate())
				.to("mock:doNothing")
			.otherwise()
				.to("mock:doSomething1")
				.to("mock:doSomething2")
				.to("mock:doSomething3")
		.end()
;

//Sie können eine Schutzklausel mit Wahl machen, aber es ist ein wenig übertrieben
from("direct:guardByChoice")
		.choice()
			.when(new MyPredicate())
				.to("mock:doNothing")
				.stop()
		.end()

		.to("mock:doSomething1")
		.to("mock:doSomething2")
		.to("mock:doSomething3")
;

//Prägnant mit Filter
from("direct:guardByFilter")
		.filter(new MyPredicate())
			.to("mock:doNothing")
			.stop()
		.end()

		.to("mock:doSomething1")
		.to("mock:doSomething2")
		.to("mock:doSomething3")
;

split Entspricht der erweiterten for-Anweisung (für jede Anweisung) und der forEach-Methode. Listen und Zeichenketten werden getrennt und einzeln in einem neuen Austausch für die Verarbeitung verpackt.

https://camel.apache.org/components/latest/eips/split-eip.html

from("direct:sample")
		.split(body()).parallelProcessing()
			.log("content: ${body}")
			.to("mock:abc")
		.end()
;

loop, while Sie können die Anzahl der Schleifen indizieren (ab 0). Verwenden Sie loop (), um anzugeben, wie oft die for-Anweisung verwendet werden soll, und loopDoWhile (), um die Bedingung wie die while-Anweisung anzugeben.

https://camel.apache.org/components/latest/eips/loop-eip.html

from("direct:sample")
		.loop(100).copy()
			.log("index: ${exchangeProperty[CamelLoopIndex]}")
			.to("mock:abc")
		.end()
;

try … catch … finally Es gibt auch eine Ausnahmebehandlung.

https://camel.apache.org/manual/latest/try-catch-finally.html

Wiederum werden gemäß der Java-Syntax "doTry ()", "doCatch ()", "doFinally ()" und "end ()" gleich eingerückt, und das Innere von jedem wird um einen Schritt abgesenkt.

Beispiel: https://github.com/apache/camel/blob/camel-2.25.1/camel-core/src/test/java/org/apache/camel/processor/TryProcessorMultipleExceptionTest.java

TryProcessorMultipleExceptionTest.java


from("direct:start")
		.doTry()
			.process(new ProcessorFail())
			.to("mock:result")
		.doCatch(IOException.class, IllegalStateException.class)
			.to("mock:catch")
		.doFinally()
			.to("mock:finally")
		.end()
;

Ist das Argument eine Methodenkette?

Die folgende Methode dient zum Austausch von Daten.

Es gibt zwei Methoden: "Nach Argument angeben" und "Nach Methodenkette angeben". In der Konvention ** vereinheitlichen, um "durch Argument angeben" **. Ich denke, es ist einfacher zu verstehen, ob die eine Methode, aus der die Route besteht, ein Prozess ist, wie er ist.

Es basiert auf der gleichen Idee, dass das Argument in der Strukturierung für "when ()" und "split ()" angegeben wird.

// disliked
from("direct:dislikedSample")
		.setHeader("foo").expression(new MyExpression())
		.setProperty("bar").header("foo")
		.setBody().exchangeProperty("bar")
;

// preferred
from("direct:preferredSample")
		.setHeader("foo", new MyExpression())
		.setProperty("bar", header("foo"))
		.setBody(exchangeProperty("bar"))
;

Geben Sie eine Instanz von Expression als Argument an. (Dokumentation)

Regelausnahme

Wenn es jedoch kompliziert wird, das Argument anzugeben, verwenden Sie eine Methodenkette. Schreiben Sie in diesem Fall so viel wie möglich in dieselbe Zeile.

Zum Beispiel marshal (). Es gibt auch eine Methode zum Übergeben einer Zeichenfolge als Argument, aber wenn möglich, möchte ich eine vorbereitete Konstante verwenden, um Tippfehler zu vermeiden. Dann wird das Argument länger sein.

from("direct:marshalSample")
		.marshal().json(JsonLibrary.Gson)
		.marshal(new JsonDataFormat(JsonLibrary.Gson))
;

Ausdruckserweiterung

In die Zeichenkette des Arguments von "log ()" kann dieselbe Ausdruckserweiterung wie "simple ()" (ich weiß nicht, ob es heißt ...) geschrieben werden.

https://camel.apache.org/components/latest/languages/simple-language.html

from("direct:loggingSample")
		.log("foo :: ${header[foo]}")
		.log("bar :: ${exchangeProperty[bar]}")
		.log("baz :: ${body}")
;

Sie können leistungsfähigere Ausdrücke wie Methodenaufrufe schreiben, die detaillierten Regeln wurden jedoch noch nicht festgelegt. → https://camel.apache.org/components/latest/languages/ognl-language.html

Wählen Sie je nach Situation

Manchmal kann man etwas Ähnliches auf verschiedene Arten tun. Es ist besser lesbar, diejenige zu wählen, die dem Zweck entspricht, und diejenige, die auf den Zweck spezialisiert ist.

Protokollausgabe

Es stehen zwei Typen zur Verfügung. Sie sollten sich nicht verlaufen, da die Verwendung unterschiedlich ist.

from("direct:start")
		.log(LoggingLevel.DEBUG, "org.apache.camel.sample", "any message")
		.to("log:org.apache.camel.sample?level=DEBUG&showAll=true&multiline=true")
;

Wahl oder Filter

Wie im Abschnitt zur Strukturierung erläutert. Sie können sich vorstellen, dass filter () nur den Zweig einer if-Anweisung schreiben kann (ohne else).

Ausdruckserweiterung oder Methodenkombination

Simple Expression Language kann mithilfe der ** Ausdruckserweiterung ** (?) Verschiedene Werte und bedingte Ausdrücke erstellen. Auf der anderen Seite normale Werte (ValueBuilder) Es gibt auch Methoden, die bearbeitet werden können. Das Schreiben in einer Methode erhöht die Wahrscheinlichkeit, einen einfachen Fehler beim Kompilieren zu bemerken, aber ohne eine gute Methode ist es in der Regel lang. Welches leichter zu lesen ist, hängt von der jeweiligen Situation ab und dient nur als Referenz.

from("direct:simpleOrValue")
		// create same strings
		.setHeader("sample1", simple("hoge: ${header[hoge]}"))
		.setHeader("sample2", header("hoge").prepend("hoge: "))

		// check same conditions
		.choice()
			.when(simple("${header[CamelSqlRowCount]} != 1"))
				.log("record not unique!")
			.when(header(SqlConstants.SQL_ROW_COUNT).isNotEqualTo(1))
				.log("record not unique!")
		.end()
;

Recommended Posts

Konventionen für die Java DSL-Personalcodierung, die bei der Erstellung von Apache Camel-Routen verwendet werden
So erzwingen Sie Codierungskonventionen in Java
Java-Codierungskonvention
Lose Java-Codierungskonventionen
JavaFX-Umgebungskonstruktion in Java 13
Was ist neu in Apache Camel 2.19.0?
Apache Camel in der Cloud-Ära