
本教程详细介绍了如何在java se环境中,使用嵌入式jetty服务器、jersey框架构建restful服务,并无缝集成weld cdi实现依赖注入。文章将重点阐述正确的gradle依赖配置以及jetty与weld cdi的集成方式,以解决常见的依赖注入问题,确保应用程序的稳定运行和模块化设计。
在构建独立的Java SE应用程序时,我们常常需要一个轻量级的Web服务器来暴露RESTful API,并结合依赖注入框架来管理组件生命周期。本文将指导您如何在嵌入式Jetty服务器中,有效集成Jersey(JAX-RS实现)和Weld(CDI实现),以构建一个功能完善且易于维护的REST服务。
正确的依赖配置是成功集成的基石。为了确保Jetty、Jersey和Weld之间的兼容性,我们需要引入一系列特定的库。以下是推荐的Gradle配置,它精简了不必要的依赖,并引入了关键的jetty-cdi模块来简化集成:
plugins {
id 'application'
id 'java'
id 'eclipse'
}
repositories {
mavenCentral()
}
dependencies {
// 日志框架
implementation 'org.slf4j:slf4j-api:2.0.4'
implementation 'ch.qos.logback:logback-classic:1.4.5'
// Jetty 服务器核心与Servlet支持
implementation 'org.eclipse.jetty:jetty-servlet:11.0.12'
// Jetty CDI集成模块,关键所在
implementation 'org.eclipse.jetty:jetty-cdi:11.0.12'
// Weld Servlet环境核心,提供CDI Servlet生命周期监听器
implementation 'org.jboss.weld.servlet:weld-servlet-core:4.0.3.Final'
// Jersey RESTful框架核心与Servlet容器集成
implementation 'org.glassfish.jersey.containers:jersey-container-servlet-core:3.0.4'
// Jersey CDI 2.0 SE集成模块,与Weld 4.x版本兼容
implementation 'org.glassfish.jersey.media:jersey-cdi2-se:3.0.4'
// Jersey JSON处理支持
implementation 'org.glassfish.jersey.media:jersey-media-json-jackson:3.0.4'
// 测试依赖
testImplementation 'org.junit.jupiter:junit-jupiter:5.7.2'
}
application {
mainClass = 'it.gym.StartApp'
}
tasks.named('test') {
useJUnitPlatform()
}依赖说明:
Jetty服务器的配置是实现CDI注入的关键环节。传统的Servlet监听器配置方式无法正确地让Weld管理Jersey资源类中的注入点。我们需要利用jetty-cdi提供的机制。
以下是主应用程序类StartApp的示例,展示了如何启动Jetty并正确集成Weld CDI:
package it.gym;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.glassfish.jersey.servlet.ServletContainer;
import org.jboss.weld.environment.se.Weld;
import org.jboss.weld.environment.se.WeldContainer;
// 导入正确的CDI集成类
import org.eclipse.jetty.cdi.CdiServletContainerInitializer;
import org.eclipse.jetty.cdi.CdiDecoratingListener;
import org.jboss.weld.environment.servlet.EnhancedListener;
public class StartApp {
public static void main(String[] args) {
// 1. 初始化Weld SE容器 (虽然Weld Servlet会接管,但初始化SE容器可以确保BeanManager可用)
Weld weld = new Weld();
WeldContainer container = weld.initialize(); // 此处初始化Weld SE容器
final Server server = new Server(9000);
final ServletContextHandler context = new ServletContextHandler(
ServletContextHandler.SESSIONS);
context.setContextPath("/");
// 2. 配置Jetty与Weld CDI的集成
// 设置CDI集成模式为装饰器监听器模式
context.setInitParameter(
CdiServletContainerInitializer.CDI_INTEGRATION_ATTRIBUTE,
CdiDecoratingListener.MODE);
// 添加Jetty CDI容器初始化器
context.addServletContainerInitializer(new CdiServletContainerInitializer());
// 添加Weld增强型监听器,确保Weld在Servlet上下文中的正确生命周期管理
context.addServletContainerInitializer(new EnhancedListener());
// 3. 配置Jersey Servlet
final ServletHolder servletHolder = new ServletHolder(
ServletContainer.class);
servletHolder.setInitOrder(1);
// 指定Jersey扫描JAX-RS资源类的包路径
servletHolder.setInitParameter(
"jersey.config.server.provider.packages",
"it.gym"); // 替换为您的资源类所在的基础包
context.addServlet(servletHolder, "/rest/*"); // 将Jersey Servlet映射到/rest/*路径
server.setHandler(context);
try {
server.start();
server.join();
} catch (Exception e) {
e.printStackTrace();
} finally {
// 确保Weld容器在应用关闭时也关闭
weld.shutdown();
}
}
}关键集成点:
通过以上配置,Jetty将能够识别并正确启动Weld CDI环境,使得Jersey资源类中的@Inject注解能够正常工作。
一旦Jetty和Weld CDI集成正确,您的JAX-RS资源类和CDI Bean就可以像在任何标准EE容器中一样进行开发。
RESTful资源类 (GymEndpoint.java):
package it.gym.rest;
import java.util.List;
import it.gym.dao.GymDAO;
import jakarta.enterprise.context.RequestScoped;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.Status;
@Path("/")
@RequestScoped // 标记为请求作用域的CDI Bean
public class GymEndpoint {
@Inject // 注入GymDAO实例
private GymDAO gymDAO;
@GET
@Path("/test")
public Response test() {
List<String> entity = gymDAO.getDevices();
return Response.status(Status.OK).entity(entity).build();
}
}CDI Bean (GymDAO.java):
package it.gym.dao;
import java.util.ArrayList;
import java.util.List;
import jakarta.enterprise.context.RequestScoped;
@RequestScoped // 标记为请求作用域的CDI Bean
public class GymDAO {
public GymDAO() {
// 构造函数,Weld会负责其生命周期
}
public List<String> getDevices() {
// 模拟数据访问
List<String> devices = new ArrayList<>();
devices.add("Device A");
devices.add("Device B");
return devices;
}
}在GymEndpoint中,@Inject注解用于请求GymDAO的实例。由于GymDAO被@RequestScoped注解标记,Weld CDI容器将负责创建、管理并注入GymDAO的实例到GymEndpoint中,从而解决了“Unsatisfied dependencies”的错误。
通过本文的指导,您应该已经成功地在嵌入式Jetty服务器中集成了Jersey REST服务和Weld CDI。关键在于正确配置项目依赖,并利用jetty-cdi提供的CdiServletContainerInitializer和EnhancedListener来协调Jetty和Weld的生命周期。这种集成方式不仅解决了CDI依赖注入的问题,还为构建模块化、可维护的独立Java SE REST应用程序奠定了坚实的基础。
以上就是在嵌入式Jetty中集成Jersey REST服务与Weld CDI的指南的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号