# 27.3. JAX-RS和Jersey

如果你更喜欢JAX-RS为REST端点提供的编程模型，可以使用相应的实现代替Spring MVC。如果将Jersey 1.x和Apache CXF的`Servlet`或`Filter`注册到应用上下文中，那它们可以很好的工作。Spring对Jersey 2.x有一些原生支持，所以在Spring Boot中也为它提供了自动配置及一个starter。

想要使用Jersey 2.x，需要添加`spring-boot-starter-jersey`依赖，然后创建一个`ResourceConfig`类型的`@Bean`，用于注册所有的端点（endpoints），如下所示：

```java
@Component
public class JerseyConfig extends ResourceConfig {
    public JerseyConfig() {
        register(Endpoint.class);
    }
}
```

**警告⚠️** Jersey对扫描可执行存档的支持相当有限。例如，当运行一个可执行的war文件时，它不能扫描在`WEB-INF/classes`下找到的包中的端点。为了避免这个限制，`packages`方法不应当被使用。同时，端点应该像上面展示的那样，使用`register`方法分别注册。

你也可以注册任意数量的，实现`ResourceConfigCustomizer`的beans来进一步自定义。

所有注册的端点都需注解`@Components`和HTTP资源annotations（比如`@GET`），如下所示：

```java
@Component
@Path("/hello")
public class Endpoint {
    @GET
    public String message() {
        return "Hello";
    }
}
```

由于`Endpoint`是一个Spring组件（`@Component`），所以它的生命周期受Spring管理，你可以使用`@Autowired`注解注入依赖，也可以使用`@Value`注解注入外部配置。Jersey的servlet会被注册，并默认映射到`/*`，你可以将`@ApplicationPath`添加到`ResourceConfig`来改变该映射。

默认情况下，Jersey将以Servlet的形式注册为一个`ServletRegistrationBean`类型的`@Bean`，name为`jerseyServletRegistration`，该servlet默认会延迟初始化，不过可以通过`spring.jersey.servlet.load-on-startup`自定义。通过创建相同name的bean，你可以禁用或覆盖框架默认产生的bean。设置`spring.jersey.type=filter`可以使用filter的形式代替servlet，相应的`@Bean`类型变为`jerseyFilterRegistration`，该filter有一个`@Order`属性，你可以通过`spring.jersey.filter.order`设置。servlet和filter注册时都可以使用`spring.jersey.init.*`定义一个属性集合传递给init参数。

这里有一个[Jersey示例](https://github.com/spring-projects/spring-boot/tree/v2.0.0.RELEASE/spring-boot-samples/spring-boot-sample-jersey)，你可以查看如何设置相关事项。还有一个[Jersey 1.x示例](https://github.com/spring-projects/spring-boot/tree/v2.0.0.RELEASE/spring-boot-samples/spring-boot-sample-jersey1)。注意，在Jersey 1.x示例里，spring-boot maven plugin被配置为拆开某些Jersey jars。这样，它们就会被JAX-RS实现扫描（因为示例要求它们在`Filter`注册里接受扫描）。如果你的JAX-RS资源以内部jars的方法打包，你可能需要做同样的事情。
