Jakarta EE 10版本中的7大功能
详细了解Jakarta EE 10版本中增加的前7个功能
Java EE是Java中所有企业开发的主导力量。最近,它被更名为Jakarta EE,从JCP过渡到Eclipse Foundation。
这一转变为开放管理、开放兼容测试(早期的技术兼容工具包-TCK是闭源的),当然还有开源的大门。这意味着没有特定的厂商比其他厂商有更大的影响力;现在是更加分散的。
Jakarta EE是Java生态系统的一个组成部分。25-35%的java应用运行在JakartaEE应用服务器上。WildFly、JBoss EAP、Payara、WebSphere/Liberty、WebLogic等,都是应用服务器的一些例子。这些应用服务器是由不同的供应商开发和维护的。然而,作为一种技术,Jakarta EE仍然是供应商中立的,这意味着同样的应用程序代码应该在任何应用服务器中运行,因为所有供应商都遵守Jakarta EE的规范。
70-80%的java应用以这种或那种方式使用Jakarta EE的API。例如Tomcat, Hibernate, ActiveMQ, Jetty, CXF, Jersey, RESTEasy, Quarkus, Microprofile, Spring。如果我们再深入一点,就会发现Java应用背后的Jakarta EE APIs。
Jakarta EE是一个生动的生态系统。我们有Jakarta EE 9,Jakarta EE 9,MicroProfile,和Helidon。在Micronaut和Helidon之后推出的Quarkus,仍然是一个受欢迎的框架。许多应用程序还没有迁移;这就是为什么Java EE 8仍然存在。然而,Jakarta EE 9也许被认为是创新的基础,以推动即将发布的Jakarta EE 10的新功能。
Jakarta EE 9将所有相关的规范javax 到Jakarta命名空间。不幸的是,这导致了一些破坏性的变化,但迁移看起来相当容易。有一些工具可以做到这一点。它还删除了旧的废弃技术,并将Java 8移至Java 11。
在进入Jakarta EE 10的许多特性中,我将讨论最重要的7个特性。
1.@ManagedExecutorDefinition
在Jakarta Concurrency API中最常用的服务之一是ManagedExecutorService。它被用来在Jakarta EE环境中创建一个线程池,以一种更易于管理的方式产生线程。尽管它与ExecutorService基本相同,但我们在Java SE环境中使用它。
为了配置线程池,我们有一个供应商特定的设置。现在只需用注解就可以定义它。这是配置线程池的一种更标准的方式。
package ca.bazlur;
import static jakarta.enterprise.concurrent.ContextServiceDefinition.APPLICATION;
import static jakarta.enterprise.concurrent.ContextServiceDefinition.SECURITY;
import jakarta.annotation.Resource;
import jakarta.ejb.Asynchronous;
import jakarta.enterprise.concurrent.ContextServiceDefinition;
import jakarta.enterprise.concurrent.ManagedExecutorDefinition;
import jakarta.enterprise.concurrent.ManagedExecutorService;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Named;
import java.time.Duration;
import java.time.LocalDate;
import java.util.concurrent.CompletableFuture;
@Named
@ApplicationScoped
@ManagedExecutorDefinition(
name = "java:module/concurrent/MyExecutor",
context = "java:module/concurrent/MyExecutorContext",
hungTaskThreshold = 120000,
maxAsync = 5)
@ContextServiceDefinition(
name = "java:module/concurrent/MyExecutorContext",
propagated = {SECURITY, APPLICATION})
public class WorkService {
@Resource(name = "java:app/concurrent/MyExecutorService")
private ManagedExecutorService executor;
@Asynchronous
public CompletableFuture<Long> hoursWorked(LocalDate from, LocalDate to) {
return CompletableFuture.supplyAsync(() -> heavyAPICall(from, to), executor);
}
private static long heavyAPICall(LocalDate from, LocalDate to) {
return Duration.between(from, to).toMillis();
}
}
2.@Asynchronous
在EJB中也有一个类似的注解。用这个注解的方法应该是异步运行的。然而不幸的是,EJB的注释有点过时了。
另外,在EJB中,我们不能指定线程池。它曾经使用应用服务器的默认线程池。现在的新注解是jakarta.enterprise.concurrent.Asynchronous
伴随着Jakarta EE Concurrency 3.0而来,它不需要使用EJB,我们可以指定线程池。它可以与任何CDI bean一起使用。每个异步方法的执行都对应于一个托管的java.util.concurrent.CompletableFuture 实例,该实例由jakarta.enterprise.concurrent.ManagedExecutorService 作为其默认的异步执行设施。
package ca.bazlur;
import jakarta.enterprise.concurrent.Asynchronous;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Named;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
@Named
@ApplicationScoped
public class PaymentService {
@Asynchronous(executor = "java:app/concurrent/MyExecutorService")
public CompletableFuture<Confirmation> processPayment(final Order order) {
try {
var status = processOrder(order);
return CompletableFuture.completedFuture(status);
} catch (PaymentException ex) {
throw new CompletionException(ex);
}
}
private Confirmation processOrder(Order order) {
return new Confirmation();
}
}
class PaymentException extends RuntimeException {}
record Confirmation() {}
record Order() {}
3.Bootstrap API。
如果你在Jakarta EE环境之外调用一个休息服务,例如单元测试、集成测试等,有一个独立的API来做这件事是很好的。有了这个,你就不需要运行整个容器了。因此,它变得非常方便。
4.多部分/表单数据
Jakarta RESTful Web Service是开发者中流行的暴露restful端点的功能之一。然而,它并没有以一种标准的方式合理地支持多部分表单数据。这就是为什么多年来,开发人员需要Servlets或供应商特定的REST API来处理多部分媒体类型。有了Jakarta REST 3.1,我们不再需要处理这样的问题,它增加了对多部分表单数据的全面支持,这是标准的。
package ca.bazlur;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.FormParam;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.core.EntityPart;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import java.io.InputStream;
@Path("/job")
public class FileResource {
@Path("/apply")
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response applyForJob(
@FormParam("name") String name, @FormParam("recentPhoto") EntityPart photo,
@FormParam("resume") EntityPart resume) {
processApplication(name,
photo.getMediaType(), photo.getContent(), resume.getMediaType(), resume.getContent());
return Response.ok("Application received").build();
}
private void processApplication(String name, MediaType mediaType, InputStream content,
MediaType mediaType1, InputStream content1) {
}
}
5.@OpenIdAuthenticationDefinition
好吧,多年来,我们一直在使用用户名和密码来验证Web应用程序中的用户。然而,在现代应用中,使用其他服务来登录已经变得很普遍,例如Facebook、Google、Twitter等。OpenID Connect协议为这种认证提供了动力。有了Jakarta Security 3.0,我们现在有了一种标准的方式来遵守OpenID Connect,只需使用一个注释,即@OpenIdAuthenticationDefinition。现在的生活简单多了;指定所需的属性,如提供者URI、clientId、clientSecret、重定向URI等。
Java
@OpenIdAuthenticationDefinition(
providerURI = "https://sample-openid-server.com",
clientId = "87068hgfg5675htfv6mrucov57bknst.apps.sample.com",
clientSecret = "{my-secret}",
redirectURI = "${baseURL}/callback",
extraParameters = {
"testKey=testValue",
"testKey2=testValue2"
}
)
public class SecurityConfig {
}
6.UUID密钥
Jakarta Persistence 3.1带来的java.util.UUID 是作为一个基本类型的字段,这对云环境的实体ID非常方便,因为许多数据库不会自动生成UUID。
爪哇
package ca.bazlur;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import java.util.UUID;
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private UUID id;
private String username;
private String password;
}
此外,它还为查询语言和Criteria API带来了几个功能。这些新的功能分为三类:
- 数字函数(CEILING, EXP, FLOOR, LN, POWER, ROUND, SIGN)
- 使用Java.time类型返回当前本地日期和时间的函数(LOCAL DATE, LOCAL DATETIME, LOCAL TIME)。
- EXTRACT函数从一个给定的日期中提取数字部分(YEAR, QUARTER, MONTH, WEEK, DAY, HOUR, MINUTE, SECOND)。
7.使用纯Java的Jakarta Faces视图
Jakarta Faces 4.0带来了一个新的API,可以只用Java代码定义完整的视图(HTML页面)。因此,如果你对编写任何类型的标记语言特别不感兴趣,你现在可以用纯Java面孔视图完全用Java编写你的UI代码。我喜欢它。
现在介绍一下Jakarta EE的大使们。我们是一个独立的草根团体,致力于通过积极的社区参与和宣传来推动Jakarta EE的发展。如果你想加入并做出贡献,请在这里了解更多:https://jakartaee-ambassadors.io/。整个Jakarta 10平台的最终发布将在下个月晚些时候。在这里了解更多。Jakarta EE 10的发布计划。
最后,如果你想了解更多关于Jakarta EE的情况,请观看Reza Rahman的这个会议。
今天的内容就到这里了。