Quarkus中RESTEasy?Reactive集成合并master分支
前言
Quarkus和RESTEasy團(tuán)隊(duì)非常高興地宣布了Quarkus中的RESTEasy Reactive集成已進(jìn)入master分支,并將成為下一個(gè)Quarkus 1.11發(fā)行版的一部分。我們期待每個(gè)人對(duì)其進(jìn)行測(cè)試。并為我們提供盡可能多的反饋。以典型的Quarkus方式,該項(xiàng)目可作為一組新的擴(kuò)展使用。這是一個(gè)非常令人興奮的消息,所以博主用自己蹩腳的英語(yǔ)+google翻譯翻譯了官方的公告,迫不及待的想要和大家分享。
它是什么?
正如您可能從名稱中猜到的那樣,該工作是從頭開始編寫的新JAX-RS實(shí)現(xiàn),可在我們的通用Vert.x層上工作,因此具有完全的反應(yīng)性,同時(shí)還與Quarkus緊密集成,因此移動(dòng)了很多特定于框架的工作(例如注釋掃描和元模型生成)以建立時(shí)間。
為什么非常重要?
最簡(jiǎn)單的答案是,您可以繼續(xù)利用廣泛使用且功能強(qiáng)大的JAX-RS API為應(yīng)用程序公開REST層,同時(shí)顯著提高應(yīng)用程序可以實(shí)現(xiàn)的最大吞吐量。該應(yīng)用程序還應(yīng)該稍微加快啟動(dòng)速度,并占用更少的內(nèi)存。
我們的基準(zhǔn)測(cè)試表明,此新擴(kuò)展的可測(cè)量性能幾乎與我們使用Quarkus的Reactive Routes API(它本身是一個(gè)非常有趣的API,但通常級(jí)別較低)所達(dá)到的性能相同,更不用說這是開發(fā)人員需要學(xué)習(xí)的新API)。
此外,將我們的結(jié)果與提供基于注釋的REST層的其他競(jìng)爭(zhēng)企業(yè)Java框架進(jìn)行比較時(shí),根據(jù)基準(zhǔn),Quarkus提供的吞吐量是原來的兩倍。
還有什么其他好處?
好像熟悉的API和新擴(kuò)展的改進(jìn)的運(yùn)行時(shí)特性還不夠,我們添加了一些真正令人興奮且方便的新功能(這些功能不是JAX-RS規(guī)范的一部分),這些功能是社區(qū)所要求的,或者我們覺得可以改善開發(fā)人員的體驗(yàn),并減輕某些規(guī)范的毛病。這些新功能是:
- 默認(rèn)不阻塞:現(xiàn)在,默認(rèn)情況下,所有端點(diǎn)都在IO線程上運(yùn)行。您可以@Blocking用來更改它。
- 計(jì)分系統(tǒng):在開發(fā)人員模式啟動(dòng)時(shí),該應(yīng)用程序?qū)槟@示端點(diǎn)列表,以及性能得分,告訴您為什么端點(diǎn)比最佳版本慢。這有助于弄清楚如何提高REST性能。
新的請(qǐng)求/響應(yīng)過濾器設(shè)計(jì)
JAX-RS過濾器需要實(shí)現(xiàn)一個(gè)接口并將上下文對(duì)象作為字段注入,這既昂貴又不靈活?;谖覀?cè)赒uarkus構(gòu)建系統(tǒng)中的成功,現(xiàn)在過濾器只是帶有注釋的方法,并且會(huì)自動(dòng)注入任何參數(shù):
public class CustomContainerRequestFilter { @ServerRequestFilter public void whatever(UriInfo uriInfo, HttpHeaders httpHeaders, ContainerRequestContext requestContext) { String customHeaderValue = uriInfo.getPath() + "-" + httpHeaders.getHeaderString("some-input"); requestContext.getHeaders().putSingle("custom-header", customHeaderValue); } }
此外,如果過濾器需要執(zhí)行阻止操作,則它們可以返回Uni并且RESTEasy Reactive在執(zhí)行過濾器時(shí)不會(huì)阻止事件循環(huán)線程。
最后,盡管我們還沒有完成,但是可以很容易地將此方法擴(kuò)展到其他類型的JAX-RS Provider,從而完全不需要@Context在其代碼中使用。
新*Param注解
這些注釋意味著要用來代替JAX-RS @PathParam,@QueryParam等注釋,而不必需要指定一個(gè)名稱。我們選擇不重用相同的批注名稱的原因是為了避免與JAX-RS或其他EE規(guī)范沖突:
@POST @Path("params/{p}") public String params(@RestPath String p, @RestQuery String q, @RestHeader int h, @RestForm String f, @RestMatrix String m, @RestCookie String c) { return "params: p: " + p + ", q: " + q + ", h: " + h + ", f: " + f + ", m: " + m + ", c: " + c; }
更簡(jiǎn)單的參數(shù)和上下文注入
使用RESTEasy Reactive,您甚至不需要使用,@PathParam或者@RestPath您的參數(shù)與path參數(shù)具有相同的名稱,并且類似地,您可以跳過@Context所有已知的上下文類型,這使它更加簡(jiǎn)單:
@POST @Path("params/{p}") public String params(String p, UriInfo info) { return "params: p: " + p + ", info: " + info; }
新的最佳消息正文閱讀器/編寫器
如果在為端點(diǎn)提供服務(wù)時(shí)未調(diào)用任何篩選器和攔截器,則可以使用更高效的消息正文編寫器,這些編寫器直接寫入vert.x,并且不需要反射和注釋:
@Provider public class ServerVertxBufferMessageBodyWriter extends VertxBufferMessageBodyWriter implements ServerMessageBodyWriter{ @Override public boolean isWriteable(Class type, ResteasyReactiveResourceInfo target, MediaType mediaType) { return true; } @Override public void writeResponse(Buffer buffer, ServerRequestContext context) { context.serverResponse().end(buffer.getBytes()); } }
默認(rèn)內(nèi)容類型
返回String的端點(diǎn)默認(rèn)為產(chǎn)生文本/純文本。我們計(jì)劃對(duì)JSON和其他類型執(zhí)行相同的操作。
CDI整合
通過JAX-RS的@Context進(jìn)行的所有注入都委托給Arc。這為用戶提供了Arc帶給Quarkus所有其他部分的構(gòu)建時(shí)間注入的好處。
每類異常映射器
在JAX-RS規(guī)范中,無法對(duì)特定的JAX-RS資源類以不同的方式處理異常-所有異常映射都是以全局方式完成的。但是在RESTEasy Reactive中,您可以簡(jiǎn)單地執(zhí)行以下操作:
@Path("first") public class FirstResource { @GET @Produces("text/plain") public String throwsVariousExceptions(@RestQuery String name) { if (name.startsWith("IllegalArgument")) { throw new IllegalArgumentException(); } else if (name.startsWith("IllegalState")) { throw new IllegalStateException("IllegalState"); } else if (name.startsWith("My")) { throw new MyException(); } throw new RuntimeException(); } @ServerExceptionMapper({ IllegalStateException.class, IllegalArgumentException.class }) public Response handleIllegal() { return Response.status(409).build(); } @ServerExceptionMapper(MyException.class) public Response handleMy(SimpleResourceInfo simplifiedResourceInfo, MyException myException, ContainerRequestContext containerRequestContext, UriInfo uriInfo, HttpHeaders httpHeaders, Request request) { return Response.status(410).entity(uriInfo.getPath() + "->" + simplifiedResourceInfo.getMethodName()).build(); } }
為了自定義某些資源類的異常處理。還要注意,@ServerExceptionMapper可以像JAX-RS使用那樣以全局方式處理異常ExceptionMapper。為此,只需使用注釋不屬于Resource類的方法@ServerExceptionMapper。
其他擴(kuò)展程序也可以使用嗎?
絕對(duì)!與現(xiàn)有quarkus-resteasy擴(kuò)展集成的擴(kuò)展也與quarkus-resteasy-active擴(kuò)展集成。因此,您可以繼續(xù)使用CDI,Security,Metrics,JSON,Qute,Bean Validation,OpenAPI, 并享受開箱即用和完善的開發(fā)經(jīng)驗(yàn)。
該如何嘗試?
該項(xiàng)目已降落在Quarkus主分支,所以,如果你渴望嘗試一下,你就必須按照從源代碼編譯Quarkus這和使用遵循正確BOM和版本此??捎玫腞ESTEasy Reactive擴(kuò)展為:
quarkus-resteasy-reactive
quarkus-resteasy-reactive-jackson
quarkus-resteasy-reactive-jsonb
quarkus-resteasy-reactive-qute
些擴(kuò)展等效于現(xiàn)有的quarkus-resteasy *擴(kuò)展,因此只需在應(yīng)用程序中從quarkus-resteasy-jackson切換到quarkus-resteasy-reactive-jackson,即可讓您嘗試通過Jackson集成進(jìn)行RESTEasy Reactive。
此外,如果需要使用JAX-RS客戶端,則可以使用quarkus-jaxrs-client擴(kuò)展(這不是聲明性的MicroProfile REST客戶端,而是JAX-RS規(guī)范指定的程序化客戶端)。
應(yīng)該注意什么?
首先要注意的是,目前暫時(shí)將這組擴(kuò)展視為實(shí)驗(yàn)性的。盡管該項(xiàng)目幾乎通過了JAX-RS TCK的全部,但它只是第一個(gè)發(fā)行版,因此請(qǐng)記住,它可能比典型的經(jīng)過戰(zhàn)斗的庫(kù)具有更多的錯(cuò)誤,而某些新的API和SPI可能會(huì)損壞。盡管這是第一個(gè)發(fā)行版,但我們確實(shí)預(yù)想這項(xiàng)工作將在不久的將來成為Quarkus的默認(rèn)REST層。
如新功能部分所述,默認(rèn)情況下,請(qǐng)求是在事件循環(huán)線程上處理的。這樣可以確保最大的吞吐量,但是也意味著不應(yīng)在這些線程上執(zhí)行任何阻塞工作。如果您使用Blocking IO(例如,通過使用Hibernate Panache訪問數(shù)據(jù)庫(kù)),請(qǐng)確保@Blocking在方法或類上使用注釋。這將確保該請(qǐng)求將在工作線程上得到服務(wù)。不用說,我們也非常有興趣聽到您對(duì)此默認(rèn)設(shè)置的反饋。
尚無文檔。文檔將在1.11正式版之前添加,并將逐步增強(qiáng)。該電子郵件應(yīng)包含您入門所需的所有信息,但是如果您遇到任何麻煩,我們可以在任何常用渠道(Zulip聊天,郵件列表,GitHub問題,StackOverflow)上為您提供幫助。
缺少哪些JAX-RS功能?
我們決定專注于現(xiàn)代REST層上大多數(shù)用戶的需求,而不是實(shí)現(xiàn)JAX-RS TCK所需的每個(gè)功能。因此,就這一點(diǎn)而言,RESTEasy Reactive中不提供XML支持,同時(shí)也不支持該規(guī)范的各種奧秘功能
例如:
javax.activation.DataSource
javax.annotation.ManagedBean
javax.ws.rs.core.StreamingOutput
此外,值得注意的是,第一個(gè)發(fā)行版將不包含基于新的JAX-RS客戶端(具有專用擴(kuò)展)的MicroProfile REST客戶端的實(shí)現(xiàn)。這很可能在不久的將來改變。
下一步計(jì)劃是什么?
盡管新的擴(kuò)展將隨常規(guī)的1.11版本一起提供,但我們正在考慮1.11.0.Alpha1發(fā)布一個(gè)版本,以使您盡可能容易地嘗試新的擴(kuò)展并提供早期反饋。我們非常期待聽到您在Quarkus中使用RESTEasy Reactive的想法和經(jīng)驗(yàn),并計(jì)劃充分利用它來進(jìn)一步改進(jìn)該項(xiàng)目。
以上就是Quarkus中RESTEasy Reactive集成合并master分支的詳細(xì)內(nèi)容,更多關(guān)于RESTEasy Reactive集成合并master的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
詳解Java程序啟動(dòng)時(shí)-D指定參數(shù)是什么
java服務(wù)啟動(dòng)的時(shí)候,都會(huì)指定一些參數(shù),下面這篇文章主要給大家介紹了關(guān)于Java程序啟動(dòng)時(shí)-D指定參數(shù)是什么的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2022-12-12淺談Java list.remove( )方法需要注意的兩個(gè)坑
這篇文章主要介紹了淺談Java list.remove( )方法需要注意的兩個(gè)坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-12-12Java ScheduledExecutorService定時(shí)任務(wù)案例講解
這篇文章主要介紹了Java ScheduledExecutorService定時(shí)任務(wù)案例講解,本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08Spring 使用 feign時(shí)設(shè)置header信息的操作
這篇文章主要介紹了Spring 使用 feign時(shí)設(shè)置header信息的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08Springboot使用thymeleaf動(dòng)態(tài)模板實(shí)現(xiàn)刷新
這篇文章主要介紹了Springboot使用thymeleaf動(dòng)態(tài)模板實(shí)現(xiàn)刷新,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08如何使用SpringBootCondition更自由地定義條件化配置
這篇文章主要介紹了如何使用SpringBootCondition更自由地定義條件化配置,幫助大家更好的理解和學(xué)習(xí)使用springboot框架,感興趣的朋友可以了解下2021-04-04