Die Komplexität soll also dadurch verringert werden, dass immer neue
Sachen eingeführt werden, die man auch mit der Programmiersprache
erledigen könnte?
Das führt dann zu solchen Auswüchsen:
<property name="randomNumber" value="#{ T(java.lang.Math).random() *
100.0 }"/>
Man muss also erstmal die Syntax der Spring Expression Language
lernen und dann hat man aus Sicht des Compilers auch erstmal nur
einen String vor sich, so dass die IDE Fehler in solchen Ausdrücken
nicht erkennen kann. Die IDEs mit immer neuen Funktionen zu
erweitern, um sowas zu unterstützen ist auch nicht der richtige Weg,
denn damit müssen alle IDEs das Rad neu erfinden, statt sich auf die
sowieso unterstützte Programmiersprache (hier Java) zu verlassen.
http://static.springsource.org/spring/docs/3.0.x/spring-framework-ref
erence/html/expressions.html
Es gibt zugegebenermaßen auch weniger scheußliche Beispiele, aber
auch da wäre die SPEL nicht nötig.
public static class FieldValueTestBean
@Value("#{ systemProperties['user.region'] }")
private String defaultLocale;
...
}
Das könnte man auch so machen:
private String defaultLocale = getSystemProperty("user.region");
wobei getSystemProperty eine allgemein verfügbare (statische) Methode
wäre, die diesen Wert setzt. Falls der Wert nicht gesetzt ist, könnte
null oder ein Standardwert zurückgegeben werden. Man könnte diesen
Wert dann auch noch nachträglich mit einer set-Methode überschreiben.
Der Vorteil dieses Ansatzes ist, dass man keine neue Sprache braucht
und auch die IDE den Code versteht.
Bei einigen neueren Entwicklungen in der Java-Welt handelt es sich im
Prinzip um Umgehungslösungen für Beschränkungen der Sprache. Da
sollten sich die Entwickler vielleicht mal fragen, ob nicht eine
mächtigere Sprache wie Scala besser wäre, als immer neue Krücken und
dynamische Code-Interpretation in Frameworks einzuführen.
Ein schönes Beispiel für diese Entwicklung ist auch Spring Roo,
sozusagen ein Ruby on Rails für Java. Mit Hilfe Aspektorientierter
Programmierung werden Domainklassen dabei sogar Felder wie ID oder
Version hinzugefügt. Man kann natürlich argumentieren, dass die ID
ein technischer Aspekt ist, den man so heraushält, aber aus meiner
Perspektive sollten Aspekte das Verhalten verändern und nicht neue
Werte einfügen. Zumal der Code nicht gerade nachvollziehbarer wird,
wenn man zur Laufzeit alles mögliche hinzufügt. Dazu kommt noch, dass
Spring AOP relativ langsam ist.
In Scala würde man dafür wohl einfach einen Trait (sowas wie ein
Mixin in Ruby) verwenden:
trait Entity {
@Id
var id: Long
var version: Long
}
Eine Domainklasse würde das dann so verwenden:
class Car extends Vehicle with Entity {
...
}
Aus meiner Sicht geht Spring in die falsche Richtung und wird zu
Gunsten vordergründiger vereinfachungen insgesamt immer komplexer.