最近更新
本章节包含 Jmix 框架和 Studio 2.5 的新功能介绍,以及在升级框架版本时需要注意的一些破坏性改动。
如何升级
如需新建 Jmix 2.5 项目或者升级已有项目,需要使用 Studio 2.5 以上版本。因此,请先 升级 Jmix Studio 插件。 IntelliJ IDEA 的最低版本要求是 2024.2。 |
参阅 升级项目 部分的介绍了解如何使用 Studio 升级项目。自动升级迁移过程会对项目做如下修改:
-
升级 Jmix BOM 的版本,BOM 又定义了所有依赖的版本。
-
升级 Jmix Gradle 插件的版本。
-
Gradle 包装器版本更新至 8.12.1,见
gradle/wrapper/gradle-wrapper.properties
。 -
迁移了对
NotInstantiatedList
和NotInstantiatedSet
类的导入。参考 下面内容。 -
如果项目包含了 REST API 扩展组件,则设置 jmix.rest.inline-fetch-plan-enabled 为
false
。参考 下面内容。 -
如果项目包含了 Authorization Server 扩展组件,则设置 jmix.authserver.use-in-memory-authorization-service 为
true
。参考 下面内容。
请参考破坏性改动的 完整列表,并在升级后做相应修复。
如果项目升级并启动应用程序后,遇到以下异常:
需要从项目目录删除这些文件或文件夹: 另外,如果安装了全局的 Node.js,则需要升级至 https://nodejs.org 列出的最新的 LTS 版本。 |
新功能和改进
Studio 改进
热部署提示
Studio 可以在支持热部署的文件(视图控制器和 XML,消息包,角色等)右上角显示一个新的图标,以提示当前文件的热部署状态。
这个指示器的作用是持续为开发人员提示源码中最新更改是否已经发布到运行中的应用程序。
Jmix Run/Debug 配置
我们引进了一个新的 Jmix run/debug 配置,可以替代标准的 Gradle 配置。当在 IDE 中打开 Jmix 项目时自动创建该配置。可以通过 Jmix 图标辨别新的配置。
与 Gradle 配置相比,新的 Jmix 配置可以停止应用程序而不产生任何控制台错误。
在 Run/Debug Configurations 窗口中可以点击 Add New Configuration 然后选择 Jmix Application 创建 Jmix run/debug 配置。如果右键点击 Jmix 工具窗口的根节点并选择 Start Application 也会创建这个配置。
classNames 编辑器和自动完成
Studio 对于 UI 组件 classNames
属性值的输入提供了高级支持。当在视图 XML 中编辑时,提供了 CSS 类名的自动完成选项。Jmix UI 组件提供了一个可以选择类名的编辑器窗口。
可用的类名从以下来源获取:
-
com.vaadin.flow.theme.lumo.LumoUtility
类及其内部类。 -
io.jmix.flowui.themes.JmixLumoUtility
类。 -
任何使用
@ThemeUtilityClasses
注解的自定义类。可以在你自己的扩展组件或应用程序中提供共享的类名。
按标签生成 OpenAPI 客户端
当按照 Integrating Applications Using OpenAPI 指南通过 OpenAPI 结构生成客户端代码时,可以只选择 API 结构中的部分标签。这样在集成时如果不需要所有的路径,可以减少生成的代码量。
消息模板扩展组件
消息模板 扩展组件支持创建可重用的消息模板,用于发送电子邮件或应用内通知。
多标签应用程序模式(试验)
多标签应用程序模式 扩展组件支持在应用程序主视图的标签页中打开视图。
这个扩展组件通过在主视图标签样打开视图透明地替换了 页面导航 功能。也可以使用 ViewBuilders
bean 在当前主视图标签页、新标签页或对话框窗口中打开视图。
多标签应用程序模式扩展组件目前还处于试验阶段,可能在下一个 Jmix 版本中可能会发生重大改动。 |
高级 BPM 任务列表视图
现在可以通过视图创建向导的 BPM: Advanced task list view 模板生成高级 BPM 任务列表视图。
这个视图比内置的 My tasks 多了一些功能并可以在项目中根据需要自定义。
参阅 GitHub issue #3752。
DataGrid 空状态
dataGrid 数据网格 组件现在支持 emptyStateComponent
和 emptyStateText
属性,用于在没有数据的时候显示一些内容。
REST API 和 REST 数据存储改进
REST API 和 REST 数据存储中的 Fetch Plans
在之前的版本中,通用 REST 端点仅能接受定义在共享 fetch plan 存储库中的命名 fetch plan 的名称。现在可以用 JSON 格式传递任意的 fetch plan。参阅 内联 Fetch Plans。
这个功能会影响 REST 数据存储 的使用:现在无需在客户端和服务端应用程序中定义所有的 fetch plan。而是与视图和 Java 代码一样,可以只在客户端使用内联的 fetch plan。
REST API 开放了一个新的 能力 API。可以为客户端提供通用 REST API 功能的相关信息。目前 /capabilities
端点返回的 JSON 对象仅包含一个属性:inlineFetchPlans
。如果这个属性值为 true
,表示启用了内联 fetch plan。否则,客户端仍然只能传递命名 fetch plan。
可以通过应用程序属性 jmix.rest.inline-fetch-plan-enabled 禁用 REST 中的内联 fetch plan。当使用 Studio 从低版本 Jmix 升级至 2.5 时,会设置这个属性为 false
,避免意外的数据泄露。
参阅 GitHub issue #4031。
在 REST 数据存储使用文件存储
REST 数据存储现在包含了一个特殊的 FileStorage
实现,可以通过 /files
端点操作远端应用程序文件存储中的文件。参阅 REST 数据存储:文件存储。
参阅 GitHub issue #4119。
REST API 的会话
Jmix Sessions 扩展组件提供了在使用相同 token 的 REST 请求之间维护会话的功能。在 build.gradle
中添加下面的内容可以使用这个组件:
implementation 'io.jmix.sessions:jmix-sessions-starter'
参阅 GitHub issue #3915。
实体 ID 使用 UUIDv7
现在为带了 @JmixGeneratedValue
注解的 UUID
属性生成 ID 时使用了 UUIDv7。这个版本的 UUID 是基于时间的,更适合自然排序和数据库主键。
UuidProvider
类的 createUuidV7()
方法现在默认用在 EntityUuidGenerator
bean 中。如果仍然需要使用之前版本的 UUID,请设置应用程序属性:
jmix.core.legacy-entity-uuid=true
参阅 GitHub issue #3424。
Copier 接口
新的 Copier
接口提供了 copy(Object)
方法,可以复制实体。语义上与 MetadataTools.deepCopy(Object)
类似,但是不同之处在于,新方法的实现不依赖元数据,仅通过 Java 的序列化复制对象的状态。
可以用 Copier
从 UI 中分离实体,并中视图中将分离的实体发送给自定义服务。DataContext
在通过 DataManager
保存实体时,也使用这个接口复制实体。
参阅 GitHub issue #3937。
当前语言环境查询参数
现在可以在查询语句中与 current_user_ 前缀的参数一样使用预定义的 current_locale
查询参数。示例:
select e from Region e where e.locale = :current_locale
参数值是当前用户会话中的语言环境设置,从 CurrentAuthentication 对象获取。
参阅 GitHub issue #3958。
热部署文件夹清理
在之前的版本中,热部署的文件夹 .jmix/conf
仅在执行 Studio 的启动应用程序之前的 Clean Hot Deploy Conf Directory
任务中清理。
为了确保清理工作更加可靠,且不依赖 Studio,我们在 Jmix Gradle 插件中添加了 cleanConf
任务。这个任务在每次启动程序的 bootRun
任务之前执行。
如果该功能出现了任何异常,可以在 build.gradle
添加下面的属性禁用 cleanConf
任务:
jmix {
// ...
confDirCleanupEnabled = false
}
参阅 GitHub issue #3451。
破坏性改动
复选框的必选状态
checkbox 复选框 组件支持对 “required” 状态做验证。如果复选框由于其自身属性 required
或由于关联一个必需的实体属性而成为必填的字段,则仅 true
值能通过验证,并且包含该复选框的详情视图才能关闭。
核心模块重构
由于重构了核心子系统对数据库相关库的依赖(GitHub issue #3918),下面这些破坏性改动可能会影响当前项目:
-
NotInstantiatedList
和NotInstantiatedSet
类从io.jmix.data.impl.lazyloading
移至io.jmix.eclipselink.lazyloading
包。这些类用来在 Kotlin 项目中初始化实体集合属性。需要更新实体中的依赖。 -
io.jmix.data.entity.ReferenceToEntity
可嵌入实体已经移除。如果项目中使用了,请自己创建一个拷贝。 -
io.jmix.flowuidata.accesscontext.UiGenericFilterModifyGlobalConfigurationContext
类移至io.jmix.flowui.accesscontext
包。 -
io.jmix.flowuidata.action.genericfilter
包内的所有类移至io.jmix.flowui.action.genericfilter
包。 -
io.jmix.securityflowui.model
包内的所有类移至io.jmix.security.model
包。 -
io.jmix.flowuidata.genericfilter.UiDataGenericFilterSupport
类功能迁移至io.jmix.flowui.component.genericfilter.GenericFilterSupport
。
参阅 GitHub issue #3982。
授权服务的 Token 存储
授权服务 扩展组件现在将 token 保存在数据库中,以确保在服务重启时能保留之前的 token。
如果正在使用 密码授权,需要定义一个 JdbcOAuth2AuthorizationServiceObjectMapperCustomizer
类型的 bean,并按如下代码实现:
import io.jmix.authserver.service.mapper.DefaultOAuth2TokenUserMixin;
import io.jmix.authserver.service.mapper.JdbcOAuth2AuthorizationServiceObjectMapperCustomizer;
// ...
@SpringBootApplication
public class MyApplication implements AppShellConfigurator {
// ...
@Bean
JdbcOAuth2AuthorizationServiceObjectMapperCustomizer tokenObjectMapperCustomizer() {
return objectMapper ->
objectMapper.addMixIn(User.class, DefaultOAuth2TokenUserMixin.class);
}
}
这里的 User
是你项目中的用户实体类。
如果在使用 token 时出现 java.lang.IllegalArgumentException: The class … is not in the allowlist
异常,则表示实体包含了某种类型的属性,这个类型在 token 序列化器中默认不支持。需要创建一个 mixin 类,扩展 DefaultOAuth2TokenUserMixin
,然后在 JdbcOAuth2AuthorizationServiceObjectMapperCustomizer
bean 中使用。示例:
package com.company.backend.security;
import com.company.backend.entity.Department;
import com.company.backend.entity.UserStep;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.jmix.authserver.service.mapper.DefaultOAuth2TokenUserMixin;
import io.jmix.core.FileRef;
import java.util.List;
public class OAuth2TokenUserMixin extends DefaultOAuth2TokenUserMixin {
@JsonIgnore
private Department department;
@JsonIgnore
private List<UserStep> steps;
@JsonIgnore
private FileRef picture;
}
如果仍然希望使用之前的内存 token 存储,设置 jmix.authserver.use-in-memory-authorization-service 应用程序属性为 true
。在通过 Studio 升级 Jmix 2.5 时,该属性默认设置为 true
,以保留相应的逻辑。
参阅 GitHub issue #4153。
FileStorageLocator 接口
为 io.jmix.core.FileStorageLocator
接口添加了 getAll()
方法。如果你有自己实现这个接口,则需要实现这个方法。参阅 GitHub issue #4119。
构造器变化
由于内部的重构(GitHub issue #4152),下列 bean 的构造器发生了变化:
-
DetailViewNavigationProcessor
-
HtmlContainerReadonlyDataBindingImpl
-
MenuItemCommands
-
UrlQueryParametersFacetProvider
-
ViewNavigationDelegate
如果你扩展了这些 bean,需要对照修改。