Eine Java -Implementierung der BigPipe -Technologie von Facebook.
JPIPE wird über benutzerdefinierte Tags implementiert und hat also kein Eindringen in den Backend -Code.
HTML ist eine Funktion, die die Vordergrundseite vervollständigt, während benutzerdefinierte Tags bestimmte Vorgänge im Hintergrund ausführen können.
Hauptsächlich anwendbar auf:
| Typ | Anzahl der Anfragen | Serverseitiger Druck | Benutzererfahrung | Webseite Ladengeschwindigkeit | Modullastreihenfolge | Schwierigkeit zu erreichen | Schwierigkeit in der Erziehung nach der Wartung |
|---|---|---|---|---|---|---|---|
| normal | 1 | Klein | Unterschied | langsam | Dokumentflussreihenfolge | Einfach | allgemein |
| Ajax | viele | groß | Gut | schnell | unsicher | Schwierigkeit | Schwierigkeit |
| Single-Thread-Bigpipe | 1 | Klein | Gut | langsam | Anpassen | allgemein | allgemein |
| Multithreaded BigPipe | 1 | Allgemein (durch Fadenpool verursacht) | Gut | Am schnellsten | unsicher | Am schwierigsten | allgemein |
| Eigentum | Typ | Ist es erforderlich | Standardwert | veranschaulichen | beschreiben |
|---|---|---|---|---|---|
| Kerngröße | int | NEIN | -1 | Anzahl der Kernfäden | Mindestanzahl von Leerlauffäden, minimale Anzahl von Threads, die ohnehin überleben werden |
| Maximale Größe | int | NEIN | 1024 | Maximale Anzahl von Threads | JPIPE kann die maximale Anzahl von Threads erstellen, die zur Verarbeitung von Pageletten verwendet werden |
| Warteschlangengröße | int | NEIN | 1024 | Maximal wartende Co-Säulenzahl | Die Anfrage ist größer als die maximale Größe und wird in die Warteschlange gestellt und wartet. |
| Aufbewahren | lang | NEIN | 60000 | Maximale Leerlaufzeit (MS) | Wenn die Anzahl der Threads die Kerngröße überschreitet, wird sie recycelt, bis die Anzahl der Threads eine Kerngröße entspricht. |
| Vorstart-alle-Kern-Threads | boolean | NEIN | FALSCH | Threadpool vorheizen | Ob Sie Kernfäden vor dem Start machen sollen |
| Eigentum | Typ | Ist es erforderlich | Standardwert | veranschaulichen | beschreiben |
|---|---|---|---|---|---|
| asynchron | boolean | NEIN | WAHR | Ob Sie Asynchron ausführen sollen |
| Eigentum | Typ | Ist es erforderlich | Standardwert | veranschaulichen | beschreiben |
|---|---|---|---|---|---|
| Domid | Saite | Ja | HTML -Dokument -ID | ||
| Bohne | Saite | Ja | Frühlingsbohnenname | ||
| var | Saite | Ja | variable Parameter | ||
| Uri | Saite | NEIN | URI -Parameter | ||
| JsMethod | Saite | NEIN | JP.View | JS -Funktion, die Daten umhüllt |
JpipeThreadPoolFactoryBean -Klasse <? xml version = " 1.0 " encoding = " UTF-8 " ?>
< beans xmlns = " http://www.springframework.org/schema/beans "
xmlns : xsi = " http://www.w3.org/2001/XMLSchema-instance "
xsi : schemaLocation = " http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd " >
< bean class = " top.ylonline.jpipe.spring.JpipeSpringFactoryBean " />
< bean id = " pool-1 " class = " top.ylonline.jpipe.threadpool.common.Pool " >
< property name = " coreSize " value = " -1 " />
< property name = " maxSize " value = " 20 " />
< property name = " preStartAllCoreThreads " value = " false " />
< property name = " keepAlive " value = " 12000000 " />
< property name = " queueSize " value = " 500 " />
</ bean >
<!-- 工场模式 -->
< bean class = " top.ylonline.jpipe.threadpool.util.JpipeThreadPoolFactoryBean " >
< property name = " pool " ref = " pool-1 " />
</ bean >
<!-- 或者
<bean class="top.ylonline.jpipe.threadpool.util.JpipeThreadPoolFactoryBean">
<property name="pool">
<bean class="top.ylonline.jpipe.threadpool.common.Pool">
<property name="coreSize" value="4"/>
<property name="maxSize" value="10"/>
<property name="preStartAllCoreThreads" value="true"/>
<property name="keepAlive" value="60000"/>
<property name="queueSize" value="500"/>
</bean>
</property>
</bean>
-->
</ beans >JpipeThreadPoolBuilder -Klasse <? xml version = " 1.0 " encoding = " UTF-8 " ?>
< beans xmlns = " http://www.springframework.org/schema/beans "
xmlns : xsi = " http://www.w3.org/2001/XMLSchema-instance "
xsi : schemaLocation = " http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd " >
< bean class = " top.ylonline.jpipe.spring.JpipeSpringFactoryBean " />
<!-- builder 模式 -->
< bean id = " jpipeThreadPoolBuilder " class = " top.ylonline.jpipe.threadpool.util.JpipeThreadPoolBuilder " >
< property name = " pool " >
< bean class = " top.ylonline.jpipe.threadpool.common.Pool " >
< property name = " coreSize " value = " 1 " />
< property name = " maxSize " value = " 1 " />
< property name = " preStartAllCoreThreads " value = " true " />
< property name = " keepAlive " value = " 1 " />
< property name = " queueSize " value = " 1 " />
</ bean >
</ property >
</ bean >
< bean id = " jpipeThreadPool-3 " factory-bean = " jpipeThreadPoolBuilder " factory-method = " build " />
</ beans > @ Bean
public JpipeSpringFactoryBean jpipeSpringFactoryBean (){
return new JpipeSpringFactoryBean ();
}
@ Bean
public JpipeThreadPoolExecutor jpipeThreadPoolExecutor () {
Pool pool = new Pool ();
pool . setCoreSize ( 10 );
pool . setMaxSize ( 1024 );
pool . setPreStartAllCoreThreads ( true );
pool . getKeepAlive ( 60000 );
pool . getQueueSize ( 512 );
// return new EagerThreadPool().getExecutor(pool);
return new JpipeThreadPoolBuilder ( pool ). build ();
}über Spring-Boot-Starter
< dependency >
< groupId >top.ylonline.jpipe</ groupId >
< artifactId >jpipe-spring-boot-starter</ artifactId >
< version >${version}</ version >
</ dependency > jpipe :
# enabled: true
pool :
pre-start-all-core-threads : true
core-size : -1
max-size : 20
queue-size : 10
keep-alive : 10000 Verwenden Sie Spring's @Service , um ein Pagelet zu definieren, um die DOExec
@ Service ( "testPagelet1" )
public class PageletServiceTest implements PageletBean {
@ Override
public Map < String , Object > doExec ( final Map < String , String > params ) {
Map < String , Object > data = new HashMap <>( params );
try {
TimeUnit . MILLISECONDS . sleep ( new Random (). nextInt ( 5000 ));
} catch ( InterruptedException e ) {
e . printStackTrace ();
}
return data ;
}
}jpipe.core.js
; ( function ( root , factory ) {
if ( typeof exports === 'object' ) {
module . exports = exports = factory ( ) ;
} else if ( typeof define === 'function' && define . amd ) {
define ( [ ] , factory ) ;
} else {
root . JP = factory ( ) ;
}
} ( this , function ( ) {
var JP = JP || ( function ( window ) {
return {
view : function ( json ) {
var id = json [ 'id' ] ;
document . getElementById ( id ) . innerHTML = json [ 'html' ] ;
}
} ;
} ( window ) ) ;
return JP ;
} ) ) ;<%@ taglib prefix="jp" uri="http://java.yl-online.top/jsp/jpipe" %></body> zu setzen, damit das Rendering des ersten Bildschirm -DOM nicht blockiert wird. < %@ page contentType="text/html;charset=UTF-8" trimDirectiveWhitespaces="true" % >
< %@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" % >
< %@ taglib prefix="jp" uri="http://java.yl-online.top/jsp/jpipe" % >
< c:set var =" ctx " value =" ${pageContext.request.contextPath} " />
< html lang =" en " >
< head >
< title > index </ title >
< meta http-equiv =" Content-Type " content =" text/html; charset=UTF-8 " />
< meta name =" viewport " content =" width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no " >
< script type =" text/javascript " src =" ${ctx}/resources/jpipe.core.js " > </ script >
</ head >
< body >
< h1 > index </ h1 >
< div id =" pagelet1 " > </ div >
< div id =" pagelet2 " > </ div >
< jp:pipe >
< jp:pagelet domid =" pagelet1 " bean =" testPagelet1 " var =" item " uri =" id=123&name=forever杨" >
< h1 > jspbody support </ h1 >
< p > ${item.id} </ p >
</ jp:pagelet >
< jp:pagelet domid =" pagelet2 " bean =" testPagelet2 " var =" item2 " uri =" id=456&name=forever杨2 " >
< h1 > jspbody support </ h1 >
< p > ${item2.name} </ p >
</ jp:pagelet >
</ jp:pipe >
</ body >
</ html >Nein: Bereitstellung in Behältern wie Tomcat und Stegy
@ Configuration
public class MvcWevConfig {
@ Resource
private freemarker . template . Configuration configuration ;
@ PostConstruct
public void setConfiguration () {
Version version = freemarker . template . Configuration . getVersion ();
DefaultObjectWrapper wrapper = new DefaultObjectWrapperBuilder ( version ). build ();
this . configuration . setSharedVariable ( "jp" , new FmHashModel ( wrapper ));
}
} < #-- < #assign pipe="top.ylonline.jpipe.freemarker.tag.PipeTag"?new() /> -- >
< #-- < #assign pagelet="top.ylonline.jpipe.freemarker.tag.PageletTag"?new() /> -- >
< html lang =" en " >
< head >
< title > index </ title >
< meta http-equiv =" Content-Type " content =" text/html; charset=UTF-8 " />
< meta name =" viewport " content =" width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no " >
< script type =" text/javascript " src =" jpipe.core.js " > </ script >
</ head >
< body >
< h1 > index </ h1 >
< div id =" pagelet1 " > </ div >
< div id =" pagelet2 " > </ div >
< @jp.pipe >
< @jp.pagelet domid="pagelet1" bean="testPagelet1" var="item" uri="id=123&name=forever杨" >
< h1 > testPagelet1 jspbody support </ h1 >
< p > ${item.id} </ p >
</ @jp.pagelet >
< @jp.pagelet domid="pagelet2" bean="testPagelet2" var="item2" uri="id=456&name=forever杨2" >
< h1 > testPagelet2 jspbody support </ h1 >
< p > ${item2.name} </ p >
</ @jp.pagelet >
</ @jp.pipe >
</ body >
</ html > < #assign pipe="top.ylonline.jpipe.freemarker.tag.PipeTag"?new() />
< #assign pagelet="top.ylonline.jpipe.freemarker.tag.PageletTag"?new() />
< html lang =" en " >
< head >
< title > index </ title >
< meta http-equiv =" Content-Type " content =" text/html; charset=UTF-8 " />
< meta name =" viewport " content =" width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no " >
< script type =" text/javascript " src =" jpipe.core.js " > </ script >
</ head >
< body >
< h1 > index </ h1 >
< div id =" pagelet1 " > </ div >
< div id =" pagelet2 " > </ div >
< @jp.pipe >
< @jp.pagelet domid="pagelet1" bean="testPagelet1" var="item" uri="id=123&name=forever杨" >
< h1 > testPagelet1 jspbody support </ h1 >
< p > ${item.id} </ p >
</ @jp.pagelet >
< @jp.pagelet domid="pagelet2" bean="testPagelet2" var="item2" uri="id=456&name=forever杨2" >
< h1 > testPagelet2 jspbody support </ h1 >
< p > ${item2.name} </ p >
</ @jp.pagelet >
</ @jp.pipe >
</ body >
</ html >FTL unterstützt die Verwendung von JSP -Tags. Wenn Ihr Projekt keine JSP -Vorlagen verwendet, wird dies nicht empfohlen. Da benutzerdefinierte JSP-Tags in der JSP-Umgebung geschrieben und betrieben werden, müssen Servlet-Container, die JSP 1.1 oder JSP 1.2 unterstützen, eingeführt werden (Servlet Container-Bereitstellungen wie Tomcat und Stett) und FTL können in Nicht-Service- und anderen Webumgebungen verwendet werden.
Eine genauere Erklärung lautet: Obwohl der Servlet -Container keine lokale JSP -Unterstützung hat, können Sie auch die JSP -Tag -Bibliothek in Freemarker verwenden. Stellen Sie einfach sicher, dass das Paket für JSP Version 1.2 (oder neuer) in der Webanwendung das Paket für JSP -Version 1.2 (oder neuer) ist. Wenn Ihr Servlet-Container JSP 1.1 nur unterstützt, müssen Sie die folgenden sechs Klassen (z. javax.servlet.servletContextListener, javax.servlet.servletContextattributelistener, javax.servlet.http.httpSessionAttributelistener, javax.servlet.http.httpsessionListener. Beachten Sie jedoch, dass der Container nur JSP 1.1 unterstützt und in der Regel frühere Versionen vor Servlet 2.3 verwendet wird, Ereignishörer dürfen nicht unterstützt werden, sodass die JSP 1.2 -Tag -Bibliothek zur Registrierung von Event -Hörern normal funktioniert.
Zum Zeitpunkt der Druckzeit: JSP wurde in Version 2.3 veröffentlicht
Verwenden Sie <#assign jp=JspTaglibs["http://java.yl-online.top/jsp/jpipe"] /> , um benutzerdefinierte JSP-Tags vorzustellen
< #assign jp=JspTaglibs["http://java.yl-online.top/jsp/jpipe"] />
< html lang =" en " >
< head >
< title > index </ title >
< meta http-equiv =" Content-Type " content =" text/html; charset=UTF-8 " />
< meta name =" viewport " content =" width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no " >
< script type =" text/javascript " src =" jpipe.core.js " > </ script >
</ head >
< body >
< h1 > index </ h1 >
< div id =" pagelet1 " > </ div >
< div id =" pagelet2 " > </ div >
< @jp.pipe >
< @jp.pagelet domid="pagelet1" bean="testPagelet1" var="item" uri="id=123&name=forever杨" >
< h1 > testPagelet1 support </ h1 >
< p > ${item.id} </ p >
</ @jp.pagelet >
< @jp.pagelet domid="pagelet2" bean="testPagelet2" var="item2" uri="id=456&name=forever杨2" >
< h1 > testPagelet2 support </ h1 >
< p > ${item2.name} </ p >
</ @jp.pagelet >
</ @jp.pipe >
</ body >
</ html > Abhängigkeit von Maven
<!-- undertow 部署 -->
< dependency >
< groupId >org.springframework.boot</ groupId >
< artifactId >spring-boot-starter-undertow</ artifactId >
</ dependency >
<!-- undertow 部署 -->
< dependency >
< groupId >javax.servlet.jsp</ groupId >
< artifactId >javax.servlet.jsp-api</ artifactId >
< version >2.3.3</ version >
</ dependency >Da Container wie Undertow keine JSP-API-Umgebung haben, müssen sie sich auf das Paket javax.servlet.jsp-api verlassen und gleichzeitig die KlassenpathTlds von Freemarker über Taglibfactory konfigurieren. Ohne diese Konfiguration wird ein Fehler gemeldet: Freemarker.ext.jsp.Taglibfactory $ taglibgettingException: Für die "http://java.yl-online.top/jsp/jpipe" JSP Taglib uri wurde keine TLD gefunden. (TLD-S werden gemäß der JSP 2.2-Spezifikation durchsucht. In Entwicklungs- und Embedded-Servlet-Container-Einstellungen benötigen Sie möglicherweise auch die "metainftldSources" und "classPathTLDs" Freemarker
Konfiguration
@ Configuration
public class MvcWevConfig {
@ Resource
private FreeMarkerConfigurer freeMarkerConfigurer ;
@ PostConstruct
public void loadClassPathTlds () {
List < String > classpathTlds = new ArrayList <>();
classpathTlds . add ( "/META-INF/Jpipe.tld" );
freeMarkerConfigurer . getTaglibFactory (). setClasspathTlds ( classpathTlds );
}
}Abhängigkeit von Maven
<!-- 外部 Tomcat 部署 -->
< dependency >
< groupId >javax.servlet</ groupId >
< artifactId >javax.servlet-api</ artifactId >
< scope >provided</ scope >
</ dependency >
< dependency >
< groupId >org.springframework.boot</ groupId >
< artifactId >spring-boot-starter-tomcat</ artifactId >
< scope >provided</ scope >
</ dependency >
< dependency >
< groupId >org.apache.tomcat.embed</ groupId >
< artifactId >tomcat-embed-jasper</ artifactId >
< scope >provided</ scope >
</ dependency >
<!-- 外部 Tomcat 部署 -->Da es bereits eine JSP-API-Umgebung in Tomcat und Jetty gibt, müssen sich hier nicht mehr auf das Paket javax.servlet.jsp-api verlassen