企业版Java核心概要简介

JakartaEE目前包含三个Profile,即Core、Web、Platform。三者之间存在包含关系,而每个Profile包含一堆JSR。关系图如下

企业版Java核心概要简介

核心概要文件(Core Profile)是企业版Java规范的一个子集,它的目标群体为微服务开发人员。

必要规范包括 Annotations, DI, CDI Lite, Interceptors, JSONP, JSONB, JAX-RS。

可选规范包括:JAXB(JAX-RS可选依赖), EL(CDI可选依赖)。

  1. Annotations

在JavaEE也被称为common-annotations,它是在JSR 175元注解规范出现后,为避免通用概念因不同厂商的技术实现带来不同的注解。

Annotations

Spring

备注

标记为资源

jakarta.annotation.Resource

org.springframework.stereotype.Repository

Resource用于指定EJB、WebService、Persistence等资源

属性/方法注入

jakarta.annotation.Resource

org.springframework.beans.factory.annotation.Autowired

@Resource默认按名称注入,找不到则按类型,支持从JNDI获取

顺序

jakarta.annotation.Priority

org.springframework.core.annotation.Order

@Priority的负值作为特殊用途

构造函数钩子

jakarta.annotation.PostConstruct

org.springframework.beans.factory.InitializingBean

Spring还支持其他init-method方式

析构函数钩子

jakarta.annotation.PreDestroy

org.springframework.beans.factory.DisposableBean

Spring还支持AutoCloseable等destroy-method方式

数据源

jakarta.annotation.sql.DataSourceDefinition

Spring可以通过在java配置类定义javax.sql.DataSource类型的bean

权限:定义角色

jakarta.annotation.security.DeclareRoles

Annotations还定义了其他权限相关注解

权限:资源角色

jakarta.annotation.security.RolesAllowed

org.springframework.security.access.annotation.Secured

spring-security的PreAuthorize注解支持表达式可以达到一样效果

权限:角色

jakarta.annotation.security.RunAs

Annotations还定义了其他权限相关注解

约束

jakarta.annotation.Nonnull
jakarta.annotation.Nullable

用于属性上则构造完不能/可能为null,用于方法上则返回值不能/可能为null

可以看到Annotations规范定义的注解数量不多,但涉及面挺广,甚至有些注解平常用不到。

  1. DI & CDI vs spring-context vs guice

DI规范定义了一系列为bean的字段/方法/构造器上注入的注解。DI和CDI的参考实现为JBoss Weld,但glassfish使用的是hk2。

DI & CDI

spring-context

guice

备注

配置方式

annotation, xml

xml, properties, jdbc, java

java

类标记为bean

jakarta.enterprise.context.NormalScope
jakarta.enterprise.inject.Stereotype
jakarta.enterprise.context.Dependent

org.springframework.stereotype.Component

JakartaEE中注解带有NormalScope、Stereotype都被当作bean

定义bean

jakarta.enterprise.inject.Produces

org.springframework.context.annotation.Bean

com.google.inject.Provides

scope

jakarta.inject.Singleton
jakarta.enterprise.context.ApplicationScoped
jakarta.enterprise.context.SessionScoped
jakarta.enterprise.context.RequestScoped

singleton, prototype; session, request, refresh; custom

com.google.inject.Singleton

可以通过JakartaEE元注解jakarta.inject.Scope自定义scope

限定注册到上下文类型

jakarta.enterprise.inject.Typed

构造器注入

jakarta.inject.Inject

org.springframework.beans.factory.annotation.Autowired

com.google.inject.Inject

spring支持Resource、Inject注解

属性注入

jakarta.inject.Inject

org.springframework.beans.factory.annotation.Autowired

com.google.inject.Inject

方法注入

jakarta.inject.Inject

org.springframework.beans.factory.annotation.Autowired

com.google.inject.Inject

默认bean

jakarta.enterprise.inject.Default

org.springframework.context.annotation.Primary

guice可以通过ImplementedBy来指定默认实现类型

限定名称

jakarta.inject.Named

org.springframework.beans.factory.annotation.Qualifier

com.google.inject.name.Named

jakarta.inject.Qualifier在JakartaEE为元注解

可选依赖

jakarta.inject.Provider

java.util.Optional
org.springframework.beans.factory.annotation.Autowired(required=false)

java.util.Optional

延迟加载

jakarta.inject.Provider

org.springframework.context.annotation.Lazy

避免循环依赖

jakarta.inject.Provider

多实例注入

jakarta.inject.Provider

java.util.Collection
java.util.Map

bean销毁清理

jakarta.enterprise.inject.Disposes

org.springframework.beans.factory.DisposableBean

spring支持对Closeable类型自动发现销毁方法进行调用

上下文初始化通知

jakarta.enterprise.context.Initialized

org.springframework.context.event.ContextStartedEvent

上下文销毁前通知

jakarta.enterprise.context.BeforeDestroyed

上下文销毁通知

jakarta.enterprise.context.Destroyed

org.springframework.context.event.ContextStoppedEvent

产生事件

jakarta.enterprise.event.Event

org.springframework.context.ApplicationEventPublisher

CDI中通过注入的Event来产生同步/异步事件

事件处理

jakarta.enterprise.event.Observes
jakarta.enterprise.event.ObservesAsync

org.springframework.context.event.EventListener

SPI

jakarta.enterprise.inject.build.compatible.spi.Discovery
jakarta.enterprise.inject.build.compatible.spi.Enhancement
jakarta.enterprise.inject.build.compatible.spi.Registration
jakarta.enterprise.inject.build.compatible.spi.Synthesis
jakarta.enterprise.inject.build.compatible.spi.Validation

org.springframework.beans.factory.config.BeanFactoryPostProcessor
org.springframework.beans.factory.config.BeanPostProcessor

CDI以元注解NormalScope标记常规范围,将DI的元注解Scope留作标记伪范围。CDI给JSF预留了ConversationScoped,此外还定义了一个特殊的伪范围Dependent。 DI和CDI规范没有定义prototype。

CDI为mvc架构模式,列如JSF,定义了内建的Stereotype:
jakarta.enterprise.inject.Model。

CDI允许销毁清理方法通过参数上的Disposes注解注入销毁对象或其它辅助对象。

开发、测试、生产环境需要生效的bean可能不一致(可参考Spring的@Profile,结合元注解@Qualifier自定义注解达到目的),或者值不一致(可参考Spring的@Value、@ConfigurationProperties)。

散落的配置写起来方便,阅读,特别是排查问题就麻烦,需要支持聚焦式配置(可参考Spring的@Configuration、@Import、@ImportResource)。

在JakartaEE中定义了Decorator类型bean,但他实现了业务逻辑接口类,所以无法像Interceptor那样关注横切点。 Decorator类型bean可以注入业务接口,并用Delegate注解来限定。 Decorator注解CDI Lite可以不支持。

  1. Interceptor vs spring-aop vs Aspectj

Interceptors规范定义了拦截器基本编程模型和语义。Interceptor参考实现为JBoss Weld。

Interceptors

spring-aop

Aspectj

织入时机

runtime

runtime or load time

compile

标记为切面

jakarta.interceptor.Interceptor

org.springframework.aop.Advisor

org.aspectj.lang.annotation.Aspect

标记为切点

jakarta.interceptor.Interceptors

org.springframework.aop.Pointcut

org.aspectj.lang.annotation.Pointcut

方法执行前

org.springframework.aop.BeforeAdvice

org.aspectj.lang.annotation.Before

方法执行后

org.springframework.aop.AfterAdvice

org.aspectj.lang.annotation.After

方法返回后

org.springframework.aop.AfterReturningAdvice

org.aspectj.lang.annotation.AfterReturning

方法异常时

org.springframework.aop.ThrowsAdvice

org.aspectj.lang.annotation.AfterThrowing

环绕方法

jakarta.interceptor.AroundInvoke

org.aspectj.lang.annotation.Around

JakartaEE支持将构造函数作为切点,允许环绕(AroundConstruct)和构造后(PostConstructor)处理。它们与销毁前(PreDestroy)处理,构成生命周期回调。

JakartaEE还支持超时回调: AroundTimeout。

AOP相关的框架、库还有JBoss AOP、AspectWerkz、Nanning等,它们和AOP联盟(aopalliance)一样,基本不再存活/更新。

  1. JSONB/JSONP vs jackson-json vs guava vs fastjson

JSONB即JSON Binding,用于规范java对象序列化成JSON消息,或JSON消息反序列化成java对象。参考实现为Eclipse Yasson。

JSONB

jackson-json

guava

fastjson

带参构造函数反序列化

jakarta.json.bind.annotation.JsonbCreator

com.fasterxml.jackson.annotation.JsonCreator
com.fasterxml.jackson.annotation.JsonProperty
com.fasterxml.jackson.annotation.JacksonInject

objenesis

com.alibaba.fastjson.annotation.JSONCreator
com.alibaba.fastjson.annotation.JSONField

builder模式

com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder

com.alibaba.fastjson.annotation.JSONType(builder = )
com.alibaba.fastjson.annotation.JSONPOJOBuilder

指定属性序列化时顺序

jakarta.json.bind.annotation.JsonbPropertyOrder

com.fasterxml.jackson.annotation.JsonPropertyOrder

com.alibaba.fastjson.annotation.JSONType(orders = )
com.alibaba.fastjson.annotation.JSONField(ordinal = )

属性别名

jakarta.json.bind.annotation.JsonbProperty

com.fasterxml.jackson.annotation.JsonProperty
com.fasterxml.jackson.annotation.JsonAlias

com.google.gson.annotations.SerializedName

com.alibaba.fastjson.annotation.JSONField(alternateNames = )

忽略属性

jakarta.json.bind.annotation.JsonbTransient

com.fasterxml.jackson.annotation.JsonIgnore
com.fasterxml.jackson.annotation.JsonIgnoreProperties
com.fasterxml.jackson.annotation.JsonIgnoreType

com.google.gson.annotations.Expose(serialize = false, deserialize = false)

com.alibaba.fastjson.annotation.JSONType(ignores = )
com.alibaba.fastjson.annotation.JSONField(serialize = false, deserialize = false)

指定日期格式化方式

jakarta.json.bind.annotation.JsonbDateFormat

com.fasterxml.jackson.annotation.JsonFormat

com.google.gson.GsonBuilder#setDateFormat

com.alibaba.fastjson.annotation.JSONField(format = )

指定数字格式化方式

jakarta.json.bind.annotation.JsonbNumberFormat

com.fasterxml.jackson.annotation.JsonFormat

com.alibaba.fastjson.annotation.JSONField(format = )

泛型

com.fasterxml.jackson.core.type.TypeReference

com.google.gson.reflect.TypeToken

com.alibaba.fastjson.TypeReference

多态

jakarta.json.bind.annotation.JsonbTypeInfo
jakarta.json.bind.annotation.JsonbSubtype

com.fasterxml.jackson.annotation.JsonTypeInfo
com.fasterxml.jackson.annotation.JsonSubTypes
com.fasterxml.jackson.databind.annotation.JsonTypeResolver

com.alibaba.fastjson.annotation.JSONType(seeAlso = {}, typeKey = )

自定义反序列化

jakarta.json.bind.annotation.JsonbTypeDeserializer

com.fasterxml.jackson.databind.annotation.JsonDeserialize

com.google.gson.JsonDeserializer

com.alibaba.fastjson.annotation.JSONType(deserializer = )

自定义序列化

jakarta.json.bind.annotation.JsonbTypeSerializer

com.fasterxml.jackson.databind.annotation.JsonSerialize

com.google.gson.JsonSerializer

com.alibaba.fastjson.annotation.JSONType(serializer = )

包/类属性可见性

jakarta.json.bind.annotation.JsonbVisibility

中间对象转换

jakarta.json.bind.annotation.JsonbTypeAdapter

com.google.gson.annotations.JsonAdapter

属性名映射策略

jakarta.json.bind.config.PropertyNamingStrategy

com.fasterxml.jackson.databind.annotation.JsonNaming
com.fasterxml.jackson.databind.PropertyNamingStrategy

com.google.gson.FieldNamingStrategy

com.alibaba.fastjson.annotation.JSONType(naming = )
com.alibaba.fastjson.PropertyNamingStrategy

mixin

org.springframework.boot.jackson.JsonMixin
com.fasterxml.jackson.annotation.JsonAnyGetter
com.fasterxml.jackson.annotation.JsonAnySetter

com.alibaba.fastjson.JSON.addMixInAnnotations(,)

注入上下文对象

com.fasterxml.jackson.annotation.JacksonInject

引用

com.fasterxml.jackson.annotation.JsonIdentityInfo
com.fasterxml.jackson.annotation.JsonIdentityReference

jsonpath

JSONP即JSON Processing,用于规范JSON文档的解析、生成、修改及查询。参考实现为Eclipse Parsson。

JSONP

jackson-json

guava

fastjson

解析JSON

jakarta.json.stream.JsonParser

com.fasterxml.jackson.core.JsonParser

com.google.gson.stream.JsonReader

com.alibaba.fastjson.parser.DefaultJSONParser

生成JSON

jakarta.json.stream.JsonGenerator

com.fasterxml.jackson.core.JsonGenerator

com.google.gson.stream.JsonWriter

com.alibaba.fastjson.serializer.JSONSerializer

从API来看,JSONB、JSONP与jackson极其类似。

  1. JAX-RS/mvc vs spring-webmvc

JAX-RS即Java RESTful Web Services。参考实现为Eclipse Jersey。 MVC规范基于JAX-RS,所以此处将二者当作一个整体和其它规范/库进行比较。MVC规范的参考实现为Eclipse Krazo。

JAX-RS & MVC

spring-webmvc

备注

控制器

jakarta.mvc.Controller

org.springframework.stereotype.Controller

spring-webmvc的Controller注解支持命名bean

URL映射

jakarta.ws.rs.Path

org.springframework.web.bind.annotation.RequestMapping

spring-webmvc的RequestMapping可以同时指定method, params, headers, consumes, produces

限定为GET方法

jakarta.ws.rs.GET

org.springframework.web.bind.annotation.GetMapping

同上

限定为POST方法

jakarta.ws.rs.POST

org.springframework.web.bind.annotation.DeleteMapping

同上

限定为PUT方法

jakarta.ws.rs.PUT

org.springframework.web.bind.annotation.PutMapping

同上

限定为DELETE方法

jakarta.ws.rs.DELETE

org.springframework.web.bind.annotation.DeleteMapping

同上

限定为PATCH方法

jakarta.ws.rs.PATCH

org.springframework.web.bind.annotation.PatchMapping

同上。注意:非幂等,对资源进行部分修改

限定为OPTIONS方法

jakarta.ws.rs.OPTIONS

spring-webmvc在HandlerMapping中识别预检请求,根据跨域配置决定放行还是拒绝

限定为HEAD方法

jakarta.ws.rs.HEAD

获取文件大小用。spring-webmvc无对应方式,可通过GetMapping变通实现

限定为TRACE方法

限定消费的媒体类型

jakarta.ws.rs.Consumes

org.springframework.web.bind.annotation.RequestMapping(consumes = )

限定产生的媒体类型

jakarta.ws.rs.Produces

org.springframework.web.bind.annotation.RequestMapping(produces = )

绑定请求头

jakarta.ws.rs.HeaderParam

org.springframework.web.bind.annotation.RequestHeader

Jakarta MVC的绑定参数如果是复杂对象,需要实现ParamConverterProvider并注册到容器

绑定Cookie

jakarta.ws.rs.CookieParam

org.springframework.web.bind.annotation.CookieValue

同上

绑定session

org.springframework.web.bind.annotation.SessionAttribute

绑定简单查询参数

jakarta.ws.rs.QueryParam

org.springframework.web.bind.annotation.RequestParam

绑定矩阵查询参数

jakarta.ws.rs.MatrixParam

org.springframework.web.bind.annotation.MatrixVariable

绑定路径模板参数

jakarta.ws.rs.PathParam

org.springframework.web.bind.annotation.PathVariable

绑定表单参数

jakarta.ws.rs.FormParam

MIME类型需为”
application/x-www-form-urlencoded”。Spring MVC无需注解,使用java bean会自动绑定

绑定请求体

java.lang.Object

org.springframework.web.bind.annotation.RequestBody

Jakarta MVC支持将RequestScoped的bean作为属性注入Controller

绑定上传的文件

org.springframework.web.bind.annotation.RequestPart

Jakarta MVC无注解绑定文件

绑定请求属性

org.springframework.web.bind.annotation.RequestAttribute

设置默认值

jakarta.ws.rs.DefaultValue

org.springframework.web.bind.annotation.*(defaultValue = )

spring-webmvc的RequestHeader、CookieValue、RequestParam、MatrixVariable支持默认值

返回视图

java.lang.String
jakarta.mvc.View

java.lang.String
org.springframework.web.servlet.View

Jakarta MVC的@View注解用于返回固定的默认视图

返回模型和视图

jakarta.mvc.Models

org.springframework.web.servlet.ModelAndView

返回响应码

org.springframework.web.bind.annotation.ResponseStatus

Jakarta MVC无对应注解,可通过
jakarta.ws.rs.core.Response实现

返回响应体

java.lang.Object

org.springframework.web.bind.annotation.ResponseBody

Jakarta MVC通过在实现了MessageBodyWriter和MessageBodyReader的类上标记Provider来自动编解码

全局异常处理

jakarta.ws.rs.ext.ExceptionMapper

org.springframework.web.bind.annotation.ExceptionHandler

Jakarta MVC需要用@Provider注解标记实现类,将其注册到容器

编码

jakarta.ws.rs.ext.MessageBodyWriter

org.springframework.http.codec.HttpMessageWriter

解码

jakarta.ws.rs.ext.MessageBodyReader

org.springframework.http.codec.HttpMessageReader

@Encoded仅用于标记无需解码

参数转换

jakarta.ws.rs.ext.ParamConverter

org.springframework.http.converter.HttpMessageConverter

参数校验

jakarta.validation.Valid

org.springframework.validation.annotation.Validated

spring-webmvc也支持规范的注解,但自定义注解支持分组校验;Jakarta MVC支持用MvcBinding,将违规约束放到注入的BindingResult

跨域

jakarta.mvc.security.CsrfProtected

org.springframework.web.bind.annotation.CrossOrigin

本地化

jakarta.mvc.locale.LocaleResolver

org.springframework.web.servlet.LocaleResolver

Jakarta MVC支持注入MvcContext来过程控制

异步

jakarta.ws.rs.container.Suspended

org.springframework.scheduling.annotation.Async

SSE

jakarta.ws.rs.Produces(MediaType.SERVER_SENT_EVENTS)

org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter

在JAX-RS这种RESTful WebService规范出现之前,还有SOAP WebService规范,即JAX-RPC(Java API for XML-based RPC)和JAX-WS(Java API for XML-Based Web Services)。

JAX-RPC要求SEI(Service Endpoint Interface)必须继承java.rmi.Remote,方法必须抛出java.rmi.RemoteException。 而client可以从SEI或WSDL生成java代码,或使用
java.xml.rpc.ServiceFactory.loadService来获取stub,使用起来相当不便。

JAX-WS则定义了一系列注解,用于标记类为SEI的javax.jws.WebService,标记方法的javax.jws.WebMethod,标记参数的javax.jws.WebParam, 标记结果的javax.jws.WebResult和javax.jws.Oneway。 JAX-RPC要事先生成stub,而JAX-WS允许在运行时生成stub。 JAX-WS曾被纳入JavaSE。

  1. JAXB vs XStream vs jackson-dataformat-xml

JAXB即Java Architecture for XML Binding,它是JAX-WS的默认数据绑定技术, JAXB的参考实现为jaxb-impl。

JAXB使用java注解来标记java对象和XML之间的绑定关系,XStream和jackson-dataformat-xml也支持注解形式,此处就不再比较编写XML映射关系来生成代码形式的XMLBeans和JiBX。

JAXB

XStream

jackson-dataformat-xml

绑定attribute

jakarta.xml.bind.annotation.XmlAttribute

com.thoughtworks.xstream.annotations.XStreamAsAttribute

com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty(isAttribute=true)

绑定元素

jakarta.xml.bind.annotation.XmlElement

com.thoughtworks.xstream.annotations.XStreamAlias

com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty

绑定通配attribute

jakarta.xml.bind.annotation.XmlAnyAttribute

绑定通配元素

jakarta.xml.bind.annotation.XmlAnyElement

映射元素值

jakarta.xml.bind.annotation.XmlValue

com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlText

映射附件

jakarta.xml.bind.annotation.XmlAttachmentRef

映射工厂方法到元素

jakarta.xml.bind.annotation.XmlRegistry
jakarta.xml.bind.annotation.XmlElementDecl

解组对象生成方式

jakarta.xml.bind.annotation.XmlType(factoryClass= , factoryMethod=)

包映射XML命名空间

jakarta.xml.bind.annotation.XmlSchema

标记类可编组为XML

jakarta.xml.bind.annotation.XmlRootElement

default

com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement

映射类到XML Schema

jakarta.xml.bind.annotation.XmlType

com.thoughtworks.xstream.annotations.XStreamAliasType

指定编组范围

jakarta.xml.bind.annotation.XmlAccessorType

忽略类/属性/方法

jakarta.xml.bind.annotation.XmlTransient

com.thoughtworks.xstream.annotations.XStreamOmitField

属性编组顺序

jakarta.xml.bind.annotation.XmlAccessorOrder
jakarta.xml.bind.annotation.XmlType(propOrder={})

属性类型映射XML内建类型

jakarta.xml.bind.annotation.XmlSchemaType

属性编组为XML ID

jakarta.xml.bind.annotation.XmlID

属性编组为XML IDREF

jakarta.xml.bind.annotation.XmlIDREF

属性编组为base64数据

jakarta.xml.bind.annotation.XmlMimeType
jakarta.xml.bind.annotation.XmlInlineBinaryData

枚举值编组

jakarta.xml.bind.annotation.XmlEnum
jakarta.xml.bind.annotation.XmlEnumValue

list属性编组为简单类型

jakarta.xml.bind.annotation.XmlList

多态

jakarta.xml.bind.annotation.XmlSeeAlso
jakarta.xml.bind.annotation.XmlElementRef

com.thoughtworks.xstream.annotations.XStreamInclude

混杂内容

jakarta.xml.bind.annotation.XmlMixed

编解组带包装元素

jakarta.xml.bind.annotation.XmlElementWrapper

com.thoughtworks.xstream.annotations.XStreamImplicit

com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper

CDATA

com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlCData

自定义编解组

jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter

com.thoughtworks.xstream.annotations.XStreamConverter

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 共1条

请登录后发表评论

    暂无评论内容