CUBA 7的新功能
三年前,我們宣布了該框架的第二個(gè)公開(kāi)可用的主要版本。 CUBA 6是改變游戲規(guī)則的版本–許可從專(zhuān)有轉(zhuǎn)為Apache 2.0。 那些日子,我們甚至無(wú)法猜測(cè)從長(zhǎng)遠(yuǎn)來(lái)看它將把框架帶到哪里。 CUBA社區(qū)開(kāi)始呈指數(shù)級(jí)增長(zhǎng),因此我們了解了開(kāi)發(fā)人員如何使用框架的許多可能(有時(shí)甚至是不可能的)方法。 現(xiàn)在,我們很高興地宣布CUBA 7 ,我們希望這將使所有社區(qū)成員(從剛開(kāi)始CUBA和Java之旅的人到熟練的企業(yè)開(kāi)發(fā)人員和Java專(zhuān)家)的開(kāi)發(fā)工作都更加連貫和歡樂(lè)。
開(kāi)發(fā)工具
顯然,我們?cè)诤艽蟪潭壬弦獨(dú)w功于CUBA Studio 。 它顯著簡(jiǎn)化了過(guò)度使用的Java企業(yè)例程,在許多地方使它得以簡(jiǎn)化,從而在可視化設(shè)計(jì)器中進(jìn)行了瑣碎的配置:無(wú)需了解Persistence API或Gradle甚至Spring來(lái)開(kāi)發(fā)完整的功能豐富的CRUD應(yīng)用程序– Studio會(huì)做的它給你。
Studio是一個(gè)單獨(dú)的Web應(yīng)用程序,這個(gè)事實(shí)造成了一些重大限制:
- 首先,Studio不是功能齊全的IDE,因此開(kāi)發(fā)人員必須在Studio和IntelliJ IDEA或Eclipse之間切換才能開(kāi)發(fā)業(yè)務(wù)邏輯,并從便利的導(dǎo)航,代碼完成和其他必要的事情中受益,這很煩人。
- 其次,這種神奇的簡(jiǎn)單性是建立在大量源代碼解析和生成之上的。 改進(jìn)代碼生成功能將意味著朝著開(kāi)發(fā)功能齊全的IDE的方向邁進(jìn)。
我們決定依靠另一個(gè)巨人的肩膀來(lái)克服這些限制。 Studio由JetBrains合并到IntelliJ IDEA中。 現(xiàn)在,您可以將其作為IntelliJ IDEA的插件安裝,也可以作為單獨(dú)的獨(dú)立捆綁包下載。
這開(kāi)辟了新的視野:
- 其他JVM語(yǔ)言支持(首先是Kotlin)
- 改進(jìn)的熱部署
- 整個(gè)項(xiàng)目的直觀導(dǎo)航
- 更智能的提示和代碼生成器
目前,新Studio正在積極開(kāi)發(fā)中:我們正在移植舊版本中的功能。 短期計(jì)劃還計(jì)劃使用本機(jī)IntelliJ UI重新實(shí)現(xiàn)基于Web的設(shè)計(jì)師,并改善項(xiàng)目導(dǎo)航體驗(yàn)。
堆棧升級(jí)
傳統(tǒng)上,基礎(chǔ)堆棧也已進(jìn)行了重大升級(jí),例如Java 8/11,Vaadin 8,Spring 5。
默認(rèn)情況下,新項(xiàng)目使用Java 8,但是您可以通過(guò)在build.gradle文件中添加以下子句來(lái)指定Java版本:
subprojects {sourceCompatibility = JavaVersion.VERSION_11targetCompatibility = JavaVersion.VERSION_11 }由于Vaadin數(shù)據(jù)綁定API的重大更改,升級(jí)到Vaadin 8是一個(gè)巨大的挑戰(zhàn)。 幸運(yùn)的是,CUBA通過(guò)將開(kāi)發(fā)人員包裝到其自己的API層中,從Vaadin內(nèi)部提取了開(kāi)發(fā)人員。 CUBA團(tuán)隊(duì)在重新實(shí)現(xiàn)內(nèi)部結(jié)構(gòu)方面做得很出色,保持了自己的API不變。 這意味著完全可以保存兼容性,并且可以在將項(xiàng)目遷移到CUBA 7之后立即使用Vaadin 8,而無(wú)需進(jìn)行任何重構(gòu)。
官方發(fā)行說(shuō)明中提供了更新后的依賴(lài)項(xiàng)的完整列表。
新屏幕API
此部分也可以稱(chēng)為“第一個(gè)屏幕API”,因?yàn)镃UBA從未在Web客戶(hù)端層中有任何正式聲明的API。 它來(lái)自框架的歷史以及在第一階段做出的某些假設(shè):
以聲明為中心的方法–可以以聲明方式描述的所有內(nèi)容,都應(yīng)在屏幕描述符中聲明,而不是在其控制器中進(jìn)行編碼
標(biāo)準(zhǔn)屏幕(瀏覽器和編輯器)提供了具體的通用功能,無(wú)需修改它
自從第一千名成員加入我們的社區(qū)以來(lái),我們意識(shí)到“標(biāo)準(zhǔn)” CRUD屏幕的要求范圍之廣–遠(yuǎn)遠(yuǎn)超出了最初設(shè)計(jì)的功能集。 盡管如此,很長(zhǎng)一段時(shí)間以來(lái),即使沒(méi)有API層,我們也能夠處理自定義行為的請(qǐng)求-這要?dú)w功于另一個(gè)第一步假設(shè)-開(kāi)放繼承。 有效地,“開(kāi)放繼承”意味著您可以覆蓋基礎(chǔ)類(lèi)的任何公共或受保護(hù)方法,以根據(jù)需要調(diào)整其行為。 這聽(tīng)起來(lái)似乎可以治愈所有疾病,但是實(shí)際上,它甚至無(wú)法給您帶來(lái)短期合同:如果重寫(xiě)的方法將被重命名,刪除或在框架的未來(lái)版本中根本不使用怎么辦?
@UiController("new-screen") // screen id public class NewScreen extends Screen { }從上面的示例中,我們可以看到屏幕標(biāo)識(shí)符已在控制器類(lèi)的上方明確定義。 換句話(huà)說(shuō),屏幕ID和控制器類(lèi)現(xiàn)在彼此唯一對(duì)應(yīng)。 因此,好消息是,現(xiàn)在可以通過(guò)其控制器類(lèi)以安全的方式直接處理屏幕:
@Inject private ScreenBuilders screenBuilders;@Subscribe private void onBeforeClose(BeforeCloseEvent event) {screenBuilders.screen(this).withScreenClass(SomeConfirmationScreen.class).build().show(); }屏幕描述符成為補(bǔ)充部分,而不是必需的。 可以以編程方式創(chuàng)建布局,也可以將其聲明為XML屏幕描述符,該描述符由控制器類(lèi)上的@UiDescriptor批注定義。 這使控制器和布局更易于閱讀和理解–這種方法與Android開(kāi)發(fā)中使用的方法非常相似。
之前還需要在web-screens.xml文件中注冊(cè)屏幕描述符并為其分配標(biāo)識(shí)符。 在CUBA 7中,由于兼容性原因而保留了該文件,但是,以新的方式創(chuàng)建屏幕不需要進(jìn)行此類(lèi)注冊(cè)。
屏幕生命周期
新的API引入了清晰明了的屏幕生命周期事件:
- 在里面
- 初始化后
- 演出前
- 表演后
- 收盤(pán)前
- 收盤(pán)后
可以按以下方式訂閱CUBA 7中所有與屏幕相關(guān)的事件:
@UiController("new-screen") public class NewScreen extends Screen {@Subscribeprivate void onInit(InitEvent event) { }@Subscribeprivate void onBeforeShow(BeforeShowEvent event) { }}將新的API與舊的方法進(jìn)行比較,您可以看到我們沒(méi)有覆蓋鉤子方法,鉤子方法在父類(lèi)的層次結(jié)構(gòu)中被模糊地調(diào)用,但是在屏幕生命周期的明確預(yù)定義點(diǎn)中定義了邏輯。
事件處理和功能代表
在上一節(jié)中,我們學(xué)習(xí)了如何訂閱生命周期事件,那么其他組件呢? 我們是否應(yīng)該像在6.x版本中那樣將所有必需的偵聽(tīng)器分散在屏幕初始化上? 新的API非常統(tǒng)一,因此訂閱其他事件與生命周期絕對(duì)相似。
讓我們以具有兩個(gè)UI元素的簡(jiǎn)單示例為例:一個(gè)按鈕和一個(gè)Currency字段,因此其XML描述符如下所示:
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <window xmlns="http://schemas.haulmont.com/cuba/screen/window.xsd"caption="msg://caption"messagesPack="com.company.demo.web"><layout><hbox spacing="true"><currencyField id="currencyField" currency="$"currencyLabelPosition="LEFT"/><button id="calcPriceBtn" caption="Calculate Price"/></hbox></layout> </window>通過(guò)單擊按鈕,我們稱(chēng)為中間件服務(wù),返回一個(gè)數(shù)字,該數(shù)字轉(zhuǎn)到貨幣字段。 貨幣字段應(yīng)根據(jù)價(jià)格值更改其樣式。
@UiController("demo_MyFirstScreen") @UiDescriptor("my-first-screen.xml") public class MyFirstScreen extends Screen {@Injectprivate PricingService pricingService;@Injectprivate CurrencyFieldcurrencyField;@Subscribe("calcPriceBtn")private void onCalcPriceBtnClick(Button.ClickEvent event) {currencyField.setValue(pricingService.calculatePrice());}@Subscribe("currencyField")private void onPriceChange(HasValue.ValueChangeEventevent) {BigDecimal price = pricingService.calculatePrice();currencyField.setStyleName(getStyleNameByPrice(price));}private String getStyleNameByPrice(BigDecimal price) {...}}在上面的示例中,我們可以看到兩個(gè)事件處理程序:一個(gè)事件處理程序在單擊按鈕時(shí)被調(diào)用,另一個(gè)事件處理程序在currency字段更改其值時(shí)被執(zhí)行-就這么簡(jiǎn)單。
現(xiàn)在,讓我們想象一下,我們需要驗(yàn)證價(jià)格并檢查其價(jià)格是否為正。 直接的方法是在屏幕初始化時(shí)添加驗(yàn)證器:
@UiController("demo_MyFirstScreen") @UiDescriptor("my-first-screen.xml") public class MyFirstScreen extends Screen {@Injectprivate CurrencyField<BigDecimal> currencyField;@Subscribeprivate void onInit(InitEvent event) {currencyField.addValidator(value -> {if (value.compareTo(BigDecimal.ZERO) <= 0)throw new ValidationException("Price should be greater than zero");});}}在現(xiàn)實(shí)世界的應(yīng)用程序中,屏幕入口點(diǎn)通常會(huì)被此類(lèi)屏幕元素初始化程序所丟棄。 為了解決此問(wèn)題,CUBA提供了有用的注釋@Install 。 讓我們看看它對(duì)我們的案例有何幫助:
@UiController("demo_MyFirstScreen") @UiDescriptor("my-first-screen.xml") public class MyFirstScreen extends Screen {@Injectprivate CurrencyField<BigDecimal> currencyField;@Install(to = "currencyField", subject = "validator")private void currencyFieldValidator(BigDecimal value) {if (value.compareTo(BigDecimal.ZERO) <= 0)throw new ValidationException("Price should be greater than zero");}}實(shí)際上,我們將驗(yàn)證邏輯從貨幣字段委派給屏幕中的currencyFieldValidator方法。 這可能看起來(lái)有些復(fù)雜,但是,開(kāi)發(fā)人員以驚人的速度采用了此功能。
屏幕構(gòu)建器/通知/對(duì)話(huà)框
CUBA 7還通過(guò)流暢的API引入了一組有用的組件:
- ScreenBuilders結(jié)合了流利的工廠來(lái)生成標(biāo)準(zhǔn)的查找,編輯器和自定義屏幕。 以下示例顯示了如何從另一個(gè)屏幕打開(kāi)一個(gè)屏幕。 請(qǐng)注意, build()方法返回正確類(lèi)型的屏幕實(shí)例,而無(wú)需不安全地強(qiáng)制轉(zhuǎn)換它。
- 屏幕組件為創(chuàng)建和顯示屏幕提供了較低層次的抽象,而不是ScreenBuilders 。 如果需要進(jìn)行遍歷,它還提供對(duì)CUBA應(yīng)用程序中所有打開(kāi)的屏幕( Screens#getOpenedScreens )的信息的訪問(wèn)。
- 通知和對(duì)話(huà)框組件都引入了方便的自說(shuō)明界面。 這是創(chuàng)建和顯示對(duì)話(huà)框和通知的示例:
數(shù)據(jù)綁定
CUBA不僅可以通過(guò)提供具有廣泛代碼生成功能的高級(jí)可視化工具,還可以通過(guò)即用型的豐富數(shù)據(jù)感知組件集,來(lái)快速開(kāi)發(fā)后臺(tái)UI。 這些組件只需要知道它們使用什么數(shù)據(jù),其余的將自動(dòng)進(jìn)行管理,例如查找列表,選擇器字段,具有CRUD操作的各種網(wǎng)格等。
在版本7之前,數(shù)據(jù)綁定是通過(guò)所謂的數(shù)據(jù)源實(shí)現(xiàn)的-數(shù)據(jù)對(duì)象包裝單個(gè)實(shí)體或?qū)嶓w集合,以將其與數(shù)據(jù)感知組件進(jìn)行反應(yīng)性綁定。 這種方法效果很好,但是在實(shí)現(xiàn)方面卻是一個(gè)整體。 整體架構(gòu)通常會(huì)導(dǎo)致其自定義問(wèn)題,因此,在CUBA 7中,這種堅(jiān)固的巨石被分為3個(gè)數(shù)據(jù)組件:
- 數(shù)據(jù)加載器是數(shù)據(jù)容器的數(shù)據(jù)提供者。 數(shù)據(jù)加載器不保留數(shù)據(jù),它們只是將所有必需的查詢(xún)參數(shù)傳遞到數(shù)據(jù)存儲(chǔ)區(qū),并使用結(jié)果數(shù)據(jù)集提供數(shù)據(jù)容器。
- 數(shù)據(jù)容器保留加載的數(shù)據(jù)(單個(gè)實(shí)體或多個(gè)實(shí)體),并以反應(yīng)方式將其提供給數(shù)據(jù)感知組件:包裝實(shí)體的所有更改都暴露給相應(yīng)的UI組件,反之亦然, UI組件將導(dǎo)致其數(shù)據(jù)容器中的相應(yīng)更改。
- 數(shù)據(jù)上下文是功能強(qiáng)大的數(shù)據(jù)修改管理器,可跟蹤更改并提交所有修改的實(shí)體。 實(shí)體可以合并到數(shù)據(jù)上下文中,因此它將提供原始實(shí)體的副本,但唯一但非常重要的區(qū)別是:將跟蹤,存儲(chǔ)和修改對(duì)所得實(shí)體及其引用的所有實(shí)體(包括集合)的所有修改作出相應(yīng)的承諾。
數(shù)據(jù)組件可以在屏幕描述符中聲明,也可以使用專(zhuān)門(mén)的工廠DataComponents以編程方式實(shí)例化。
雜
介紹了Ufff,它是新屏幕API的最重要部分,因此讓我簡(jiǎn)要列出Web客戶(hù)端層中的其他重要功能:
- URL歷史記錄和導(dǎo)航 。 此功能通過(guò)Web瀏覽器中的“返回”按鈕解決了SPA的一個(gè)非常普遍的問(wèn)題,提供了一種將路由分配給應(yīng)用程序屏幕的簡(jiǎn)便方法,并使API能夠在其URL中反映屏幕的當(dāng)前狀態(tài)。
- 窗體而不是FieldGroup。 FieldGroup是一個(gè)數(shù)據(jù)感知組件,用于顯示和修改單個(gè)實(shí)體的字段。 它推斷運(yùn)行時(shí)為字段顯示的實(shí)際UI。 換句話(huà)說(shuō),如果您的實(shí)體中有一個(gè)Date字段,它將顯示為DateField 。 但是,如果您希望通過(guò)編程方式對(duì)此字段進(jìn)行操作,則需要將該字段注入到屏幕控制器,然后手動(dòng)將其強(qiáng)制轉(zhuǎn)換為正確的類(lèi)型(在我們的示例中為DateField )。 稍后,我們將字段類(lèi)型更改為其他類(lèi)型,并且應(yīng)用程序在運(yùn)行時(shí)崩潰…Form通過(guò)顯式字段類(lèi)型聲明解決了此問(wèn)題。 在此處找到有關(guān)此新組件的更多信息。
- 第三方 JavaScript組件的集成已大大簡(jiǎn)化,請(qǐng)按照文檔將自定義JavaScript組件嵌入到CUBA應(yīng)用程序中。
- 現(xiàn)在,可以從xml屏幕描述符中輕松定義HTML / CSS屬性,也可以通過(guò)編程方式對(duì)其進(jìn)行設(shè)置。 在此處查找更多信息。
中間件功能
之前有關(guān)新屏幕API的內(nèi)容超出了我的預(yù)期,因此在本節(jié)中,我將力求簡(jiǎn)潔!
實(shí)體變更事件
Entity Changed Event是一個(gè)Spring應(yīng)用程序事件,當(dāng)您的實(shí)體進(jìn)入數(shù)據(jù)存儲(chǔ),被物理插入并距離提交一英寸以?xún)?nèi)時(shí),將觸發(fā)該事件。 在這里,您可以提供一些附加檢查(例如,在確認(rèn)訂單之前檢查庫(kù)存中的產(chǎn)品可用性),并在其他交易將其可見(jiàn)之前(當(dāng)然,已讀取提交的隔離級(jí)別)對(duì)其進(jìn)行修改(例如,重新計(jì)算總計(jì))。 您還可以使用此事件作為通過(guò)拋出異常來(lái)中斷提交事務(wù)的最后機(jī)會(huì)–在某些特殊情況下可能很有用。
還有一種在提交發(fā)生后立即捕獲Entity Changed Event的方法。
請(qǐng)遵循文檔的本章以查看示例。
交易數(shù)據(jù)管理器
在開(kāi)發(fā)應(yīng)用程序時(shí),我們通常使用分離的實(shí)體(即不受任何事務(wù)管理的實(shí)體)進(jìn)行操作。 但是,并非總是可以使用分離的實(shí)體,尤其是在嘗試滿(mǎn)足ACID要求時(shí)-可以使用事務(wù)數(shù)據(jù)管理器時(shí)就是這種情況。 它看起來(lái)與普通的數(shù)據(jù)管理器非常相似,但在以下方面有所不同:
- 它可以加入現(xiàn)有事務(wù)(如果在事務(wù)上下文中被調(diào)用)或創(chuàng)建自己的事務(wù)。
- 它沒(méi)有提交方法,但是有保存方法,它不會(huì)導(dǎo)致立即提交,但是要等到附加的事務(wù)被提交后再進(jìn)行。
在此處找到使用它的示例。
JPA生命周期回調(diào)
最后,CUBA 7支持JPA生命周期回調(diào)。 為了不復(fù)制有關(guān)這些回調(diào)的用途的寫(xiě)得很好的信息,讓我分享一下此鏈接 , 該鏈接完全涵蓋了該主題。
兼容性呢?
對(duì)于任何主要發(fā)行版,這都是一個(gè)公平的問(wèn)題,尤其是當(dāng)有太多看似重大的更改時(shí)! 我們?cè)谠O(shè)計(jì)所有這些新功能和API時(shí)都考慮了向后兼容性:
- CUBA 7支持舊的屏幕API,并通過(guò)幕后的新屏幕API實(shí)現(xiàn):)
- 我們還提供了用于舊數(shù)據(jù)綁定的適配器,這些適配器可繼續(xù)用于舊屏幕。
因此,好消息是,從版本6到版本7的遷移路徑應(yīng)該非常簡(jiǎn)單。
結(jié)論
在結(jié)束本技術(shù)概述時(shí),我想提到還有其他重要的創(chuàng)新,尤其是在許可方面:
- Studio的10個(gè)實(shí)體限制現(xiàn)已消失
- 現(xiàn)在免費(fèi)提供報(bào)告,BPM,圖表和地圖以及全文搜索插件。
- Studio的商業(yè)版本為實(shí)體,屏幕,菜單和其他平臺(tái)元素的視覺(jué)設(shè)計(jì)師帶來(lái)了額外的開(kāi)發(fā)舒適度,而免費(fèi)版本則專(zhuān)注于使用代碼
- 請(qǐng)注意,對(duì)于6.x和更早版本的Platform和Studio許可條款保持不變!
最后,讓我再次感謝社區(qū)成員的所有支持和反饋。 希望您會(huì)喜歡版本7! 更改的完整列表通常在發(fā)行說(shuō)明中提供 。
翻譯自: https://www.javacodegeeks.com/2019/04/whats-new-cuba-7.html
總結(jié)
以上是生活随笔為你收集整理的CUBA 7的新功能的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 东莞备案价上下浮动多少(东莞备案价上调)
- 下一篇: 关于夸克的思考