** Wie unterschiedlich ist die Entwicklungsproduktivität von Spring Boot-basierten Anwendungen im Vergleich zur Entwicklung älterer Webanwendungen? ** ** **
Mit einer Webanwendung "EasyBuggy" basierend auf einer etwas alten Technologie und ihrem Klon (genau die gleiche Funktion) Vergleichen Sie einen Spring Boot-basierten "Easy Buggy Boot" mit den folgenden Zahlen, die sich auf die Entwicklungsproduktivität auswirken: Ich versuchte es.
Die Hauptunterschiede in der Konfiguration sind übrigens wie folgt.
Unterschied | EasyBuggy | EasyBuggy Boot |
---|---|---|
Basistechnologie | Servlet 3.0.1 | Spring Boot 1.5.6 (Servlet 3.0.1) |
Präsentationsfolie | ungebraucht(Einige JSP 2.2 + JSTL 1.2) | Thymeleaf 2.1.5 (Einige JSP 2.3 + JSTL 1.2) |
Java-Container | Apache Tomcat/7.0.37 | Apache Tomcat/8.5.16 |
DB-Client/Server | JDBC / Derby 10.8.3.0 | Spring JDBC 4.3.9 / Derby 10.12.1.1 (Für Java 7)Oder 10.13.1.1 (Für Java 8) |
LDAP-Client/Server | Apache DS Client API 1.0.0 / Server 1.5.5 | Spring LDAP 2.3.1 / unboundid-ldapsdk 3.2.1 |
JavaMail 1.5.1 | JavaMail 1.5.1 (Java Mail eingeführt von Spring Boot Mail 1.5.6 überschreiben) | |
Entwicklungswerkzeuge | Keiner | Spring Boot Developer Tools 1.5.6 |
Java | Unterstützt Java 6 und höher | Unterstützt Java 7 und höher |
Erstens die durchschnittliche Bauzeit. Das Ergebnis ist wie folgt.
EasyBuggy
Etwa 6 Sekunden
$ mvn package
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building easybuggy 1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
・ ・ ・(Weggelassen, weil es lang ist)・ ・ ・
[INFO] --- tomcat7-maven-plugin:2.1:exec-war-only (tomcat-run) @ easybuggy ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5.847s
[INFO] Finished at: Thu Aug 31 23:28:55 JST 2017
[INFO] Final Memory: 36M/220M
[INFO] ------------------------------------------------------------------------
EasyBuggy Boot
Etwa 12 Sekunden
$ mvn package
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building easybuggy4sb 1.0.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
・ ・ ・(Weggelassen, weil es lang ist)・ ・ ・
[INFO] --- spring-boot-maven-plugin:1.5.6.RELEASE:repackage (default) @ easybuggy4sb ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 12.448s
[INFO] Finished at: Thu Aug 31 23:26:55 JST 2017
[INFO] Final Memory: 26M/242M
[INFO] ------------------------------------------------------------------------
Ersteres ist um mehr als das Doppelte der Differenz schneller.
Die für die Überprüfung verwendete Umgebung ist übrigens CentOS 6.9 unter VMWare, CPU 4-Kerne (Intel® Xeon® X5680 bei 3,33 GHz) und Speicher 4 GB. Alle abhängigen Bibliotheken wurden lokal heruntergeladen.
Die durchschnittliche Startzeit ist wie folgt.
EasyBuggy
Ca. 3 Sekunden
$ java -jar easybuggy.jar
8 31, 2017 2:44:56 Uhr org.apache.coyote.AbstractProtocol init
Information: Initializing ProtocolHandler ["http-bio-8080"]
8 31, 2017 2:44:56 Uhr org.apache.catalina.core.StandardService startInternal
Information: Starting service Tomcat
8 31, 2017 2:44:56 Uhr org.apache.catalina.core.StandardEngine startInternal
Information: Starting Servlet Engine: Apache Tomcat/7.0.37
8 31, 2017 2:44:59 Uhr org.apache.coyote.AbstractProtocol start
Information: Starting ProtocolHandler ["http-bio-8080"]
EasyBuggy Boot
Ungefähr 15 Sekunden (ungefähr 9 Sekunden für "mvn spring-boot: run")
$ java -jar ROOT.war
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/C:/Users/ktamura/git/easybuggy4sb/target/ROOT.war!/WEB-INF/lib/logback-classic-1.1.11.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/C:/Users/ktamura/git/easybuggy4sb/target/ROOT.war!/WEB-INF/lib/slf4j-log4j12-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder]
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.5.6.RELEASE)
2017-08-31 15:08:46.454 INFO 5460 --- [ main] o.t.e.Easybuggy4sbApplication : Starting Easybuggy4sbApplication v1.0.0-SNAPSHOT on ktamura-PC with PID 5460 (C:\Users\ktamura\git\easybuggy4sb\target\ROOT.war started by k
tamura in C:\Users\ktamura\git\easybuggy4sb)
・ ・ ・(Weggelassen, weil es lang ist)・ ・ ・
2017-08-31 15:09:01.198 INFO 5460 --- [ main] o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 0
2017-08-31 15:09:01.273 INFO 5460 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2017-08-31 15:09:01.276 INFO 5460 --- [ main] o.t.e.Easybuggy4sbApplication : Started Easybuggy4sbApplication in 15.253 seconds (JVM running for 15.81)
EasyBuggy startet sehr schnell und fühlt sich selbst in 15 Sekunden langsam an. Wenn Sie sich das EasyBuggy Boot-Protokoll ansehen, ist die Verarbeitung nicht sehr zeitaufwändig, sodass möglicherweise nicht viel Raum für Verbesserungen besteht. Ich denke, dass die Startzeit von Spring Boot mindestens so viel dauern wird.
Dieses Ergebnis ist das Ergebnis des integrierten Tomcat, aber das Ergebnis ist fast dasselbe, selbst wenn die War-Datei auf dem nicht integrierten Tomcat bereitgestellt wird.
EasyBuggy Boot dauert jedoch ungefähr 9 Sekunden, wenn es mit dem Befehl mvn spring-boot: run
gestartet wird. Ich habe die Protokolle beider verglichen, um festzustellen, warum dieser Unterschied auftritt, aber es scheint, dass es keinen großen Unterschied in der ausgeführten Verarbeitung gibt, und ich kannte den klaren Grund nicht.
Die durchschnittliche Zeit von der Änderung des Quellcodes bis zur Überprüfung des Vorgangs ist wie folgt.
EasyBuggy
Etwa 15 Sekunden
EasyBuggy verwendet den Befehl mvn install
, um eine JAR-Datei zu erstellen und alles auf einmal zu starten. Der Neustart dauert ca. 15 Sekunden, einschließlich der dafür erforderlichen Zeit und des Stopps. Natürlich dauert die eigentliche Entwicklung nicht lange, da sie die Korrektur beim Debuggen mit dem Hot-Swap von JVM widerspiegelt ... (Es wird schneller sein, wenn JRebel eingeführt wird).
EasyBuggy Boot
Ca. 3 Sekunden
2017-09-01 12:04:55.414 INFO 2800 --- [ Thread-104] ationConfigEmbeddedWebApplicationContext : Closing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@27231264: startup date [Fri Sep 01 12:04:21 JST 2017]; root of context hierarchy
2017-09-01 12:04:55.417 INFO 2800 --- [ Thread-104] ationConfigEmbeddedWebApplicationContext : Closing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@4274ec33: startup date [Fri Sep 01 12:04:23 JST 2017]; parent: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@27231264
2017-09-01 12:04:55.532 INFO 2800 --- [ Thread-104] o.s.c.support.DefaultLifecycleProcessor : Stopping beans in phase 0
2017-09-01 12:04:55.537 WARN 2800 --- [ Thread-104] o.s.b.f.support.DisposableBeanAdapter : Invocation of destroy method failed on bean with name 'inMemoryDatabaseShutdownExecutor': java.sql.SQLSyntaxErrorException: Syntax error: Encountered "SHUTDOWN" at line 1, column 1.
2017-09-01 12:04:55.538 INFO 2800 --- [ Thread-104] o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.5.6.RELEASE)
・ ・ ・(Weggelassen, weil es lang ist)・ ・ ・
2017-09-01 12:04:57.895 INFO 2800 --- [ restartedMain] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8081 (http)
2017-09-01 12:04:57.897 INFO 2800 --- [ restartedMain] o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 0
2017-09-01 12:04:57.923 INFO 2800 --- [ restartedMain] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2017-09-01 12:04:57.925 INFO 2800 --- [ restartedMain] o.t.e.Easybuggy4sbApplication : Started Easybuggy4sbApplication in 2.125 seconds (JVM running for 828.681)
EasyBuggy Boot hat Spring Boot Developer Tools 1.5.6 eingeführt, sodass das Update sofort angezeigt wird und Sie nahezu ohne Wartezeit entwickeln können. Dieses Gefühl von Geschwindigkeit ist sehr angenehm.
Vergleichen wir die Anzahl der Quellcodezeilen.
EasyBuggy
Geben Sie td> ein | Leere Linie td> | Kommentarzeile td> | Code td> | Anzahl der Dateien td> |
Java | 838 | 359 | 4881 | 98 |
JSP | 11 | 10 | 810 | 6 |
XML | 5 | 0 | 47 | 2 |
HTML | 2 | 0 | 35 | 7 |
properties | 71 | 325 | 799 | 6 |
Gesamt td> | 927 | 694 | 6572 | 119 |
EasyBuggy Boot
Geben Sie td> ein | Leere Linie td> | Kommentarzeile td> | Code td> | Anzahl der Dateien td> |
Java | 663 | 131 | 3500 | 92 |
HTML | 8 | 39 | 1034 | 46 |
JSP | 0 | 4 | 149 | 2 |
XML | 0 | 1 | 32 | 4 |
SQL | 0 | 0 | 18 | 3 |
JSON | 0 | 0 | 17 | 1 |
DTD | 0 | 0 | 3 | 1 |
LDIF | 0 | 5 | 46 | 1 |
properties | 86 | 321 | 830 | 4 |
Gesamt td> | 757 | 501 | 5629 | 154 |
Die Anzahl der Zeilen im EasyBuggy-Quellcode beträgt 6.572, während der EasyBuggy-Start 5.629 beträgt. Durch die Verwendung von Spring Boot konnte die Anzahl um etwa 15% reduziert werden. Es gibt einen 1,3-fachen Unterschied in der Anzahl der Dateien, aber ich denke, das liegt daran, dass EasyBuggy den Bildschirm und die Logik nicht in separate Dateien (JSP usw.) getrennt hat (* Ich wollte einen Fehler in einer Datei erklären, also habe ich es so gemacht Ich tat).
Wie hat sich die Lesbarkeit des Quellcodes verändert? Für die folgenden Funktionen
Der Quellcode für jeden ist wie folgt.
EasyBuggy
XSSServlet.java
package org.t246osslab.easybuggy.vulnerabilities;
import java.io.IOException;
import java.util.Locale;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.t246osslab.easybuggy.core.utils.HTTPResponseCreator;
import org.t246osslab.easybuggy.core.utils.MessageUtils;
@SuppressWarnings("serial")
@WebServlet(urlPatterns = { "/xss" })
public class XSSServlet extends HttpServlet {
private static final Logger log = LoggerFactory.getLogger(XSSServlet.class);
@Override
protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
String string = req.getParameter("string");
Locale locale = req.getLocale();
StringBuilder bodyHtml = new StringBuilder();
bodyHtml.append("<form action=\"xss\" method=\"post\">");
bodyHtml.append(MessageUtils.getMsg("description.reverse.string", locale));
bodyHtml.append("<br><br>");
bodyHtml.append(MessageUtils.getMsg("label.string", locale) + ": ");
bodyHtml.append("<input type=\"text\" name=\"string\" size=\"100\" maxlength=\"100\">");
bodyHtml.append("<br><br>");
bodyHtml.append("<input type=\"submit\" value=\"" + MessageUtils.getMsg("label.submit", locale) + "\">");
bodyHtml.append("<br><br>");
if (!StringUtils.isBlank(string)) {
// Reverse the given string
String reversedName = StringUtils.reverse(string);
bodyHtml.append(MessageUtils.getMsg("label.reversed.string", locale) + " : "
+ reversedName);
} else {
bodyHtml.append(MessageUtils.getMsg("msg.enter.string", locale));
}
bodyHtml.append("<br><br>");
bodyHtml.append(MessageUtils.getInfoMsg("msg.note.xss", locale));
bodyHtml.append("</form>");
HTTPResponseCreator.createSimpleResponse(req, res, MessageUtils.getMsg("title.xss.page", locale),
bodyHtml.toString());
}
}
EasyBuggy Boot
xss.html
<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring4-4.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" th:with="lang=${#locale.language}" th:lang="${lang}">
<div th:replace="head"></div>
<body style="margin-left: 20px; margin-right: 20px;">
<div th:replace="header"></div>
<form action="xss" method="post">
<p th:text="#{description.reverse.string}" /><br />
<label th:text="#{label.string}"></label><span>: </span>
<input type="text" name="string" size="100" maxlength="100" /><br /><br />
<input type="submit" /><br /><br />
<p th:utext="${msg}" /><br />
<div class="alert alert-info" role="alert">
<span class="glyphicon glyphicon-info-sign" th:utext="#{msg.note.xss}"></span>
</div>
</form>
</body>
</html>
XSSController.java
package org.t246osslab.easybuggy4sb.vulnerabilities;
import java.util.Locale;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class XSSController {
@Autowired
MessageSource msg;
@RequestMapping(value = "/xss")
public ModelAndView process(@RequestParam(value = "string", required = false) String string, ModelAndView mav,
Locale locale) {
mav.setViewName("xss");
mav.addObject("title", msg.getMessage("title.xss.page", null, locale));
if (!StringUtils.isBlank(string)) {
// Reverse the given string
String reversedName = StringUtils.reverse(string);
mav.addObject("msg", msg.getMessage("label.reversed.string", null, locale) + " : " + reversedName);
} else {
mav.addObject("msg", msg.getMessage("msg.enter.string", null, locale));
}
return mav;
}
}
Da die Funktion selbst einfach ist, gibt es möglicherweise keinen großen Unterschied in der Lesbarkeit, aber letztere ist einfacher, die Arbeit zwischen dem Programmierer und dem Designer aufzuteilen. Wenn Sie JSP verwenden, ist das erstere natürlich nahe daran.
Recommended Posts