Guice + Jersey + Jetty 框架 - 学习笔记

news2024/11/18 19:51:27

因项目使用 Guice + Jersey + Jetty 框架,所有进行了学习,下面是学习笔记。

目录

一、Guice

1. 依赖注入方式: @Inject

2. 依赖绑定(依赖注册): bind()

3. 作用域

4. 基本使用

二、Jersey

使用内置容器为例(使用Jetty发布Jersey服务)

三、Jetty

四、Guice + Jersey + Jetty Demo


一、Guice

Guice 是谷歌推出的一个轻量级 依赖注入 框架。官网地址:GitHub - google/guice: Guice (pronounced 'juice') is a lightweight dependency injection framework for Java 8 and above, brought to you by Google.

1. 依赖注入方式: @Inject

① 构造注入

public class OrderServiceImpl implements OrderService {
    private ItemService itemService;
    private PriceService priceService;

    @Inject
    public OrderServiceImpl(ItemService itemService, PriceService priceService) {
        this.itemService = itemService;
        this.priceService = priceService;
    }
}

② 一般注入

public class OrderServiceImpl implements OrderService {
    private ItemService itemService;
    private PriceService priceService;

    @Inject
    public void init(ItemService itemService, PriceService priceService) {
        this.itemService = itemService;
        this.priceService = priceService;
    }
}
public class OrderServiceImpl implements OrderService {
    private ItemService itemService;
    private PriceService priceService;

    @Inject
    public void setItemService(ItemService itemService) {
        this.itemService = itemService;
    }

    @Inject
    public void setPriceService(PriceService priceService) {
        this.priceService = priceService;
    } 
}

2. 依赖绑定(依赖注册): bind()

Guice 提供依赖配置类:继承 AbstractModule,实现 configure 或者使用 @Provides 方法,完成依赖绑定。

Binder 语义: 
基本配置:binder.bind(serviceClass).to(implClass).in(Scopes.[SINGLETON | NO_SCOPE]); 
无base类、接口配置:binder.bind(implClass).in(Scopes.[SINGLETON | NO_SCOPE]); 
service实例配置:binder.bind(serviceClass).toInstance(servieInstance).in(Scopes.[SINGLETON | NO_SCOPE]); 
多个实例按名注入:binder.bind(serviceClass).annotatedWith(Names.named(“name”)).to(implClass).in(Scopes.[SINGLETON | NO_SCOPE]);

① 基本绑定

public class BillingModule extends AbstractModule {
  @Override 
  protected void configure() {
    bind(TransactionLog.class).to(DatabaseTransactionLog.class);
  }
}

② @Named 注解绑定(多实现绑定同一个接口)

// 1.注入的地方添加 @Named 注解
@Inject
public RealBillingService(@Named("Checkout") CreditCardProcessor processorg, TransactionLog transactionLog) {
    // ......
}

// 2.在绑定中添加 annotatedWith 方法指定 @Named 中指定的名称
bind(TransactionLog.class).to(TransactionLogImpl.class);
bind(CreditCardProcessor.class)
    .annotatedWith(Names.named("Checkout"))
    .to(CheckoutCreditCardProcessor.class);
// 1.注入
@Inject
public List<NamedService> getAllItemServices(@Named("impl1") NamedService nameService1,
                                                 @Named("impl2") NamedService nameService2) {
}
// 2.绑定
bind(NamedService.class).annotatedWith(Names.named("impl1")).to(NamedServiceImpl1.class);
bind(NamedService.class).annotatedWith(Names.named("impl2")).to(NamedServiceImpl2.class);

③ toInstance 实例绑定

bind(String.class)
    .annotatedWith(Names.named("JDBC URL"))
    .toInstance("jdbc:mysql://localhost/pizza");

④ @Provides 方法

public class BillingModule extends AbstractModule {
  @Override
  protected void configure() {
    ...
  }

  @Provides
  TransactionLog provideTransactionLog() {
    DatabaseTransactionLog transactionLog = new DatabaseTransactionLog();
    transactionLog.setJdbcUrl("jdbc:mysql://localhost/pizza");
    transactionLog.setThreadPoolSize(30);
    return transactionLog;
  }
}

3. 作用域

Guice 提供了很多作用域,有单例 Singleton,Session 作用域 SessionScoped,Request 请求作用域 RequestScoped 等等。

默认情况下 Guice 会在每次注入的时候创建一个新对象,用以下方式设置作用域:

① 实现类上添加 @Singleton 注解

@Singleton
public class InMemoryTransactionLog implements TransactionLog {
  /* everything here should be threadsafe! */
}

② 在配置类中指定

bind(TranLog.class).to(TranLogImpl.class).in(Singleton.class);

③ 在 @Provides 方法中也中指定单例

@Provides @Singleton
TransactionLog provideTransactionLog() {
    ...
}

4. 基本使用

① 引入依赖

<dependency>
    <groupId>com.google.inject</groupId>
    <artifactId>guice</artifactId>
    <version>4.1.0</version>
</dependency>

② 业务接口 和 接口实现

public interface UserService {
    void process();
}

public class UserServiceImpl implements UserService {
    @Override
    public void process() {
        System.out.println("我需要做一些业务逻辑");
    }
}

③ 注入

public interface Application {
    void work();
}

public class MyApp implements Application {
    private UserService userService;

    @Inject
    public MyApp(UserService userService) {
        this.userService = userService;
    }

    @Override
    public void work() {
        userService.process();
    }
}

④ 依赖绑定

public class MyAppModule extends AbstractModule {
    @Override
    protected void configure() {
        bind(UserService.class).to(UserServiceImpl.class);
        bind(Application.class).to(MyApp.class);
    }
}

⑤ 创建注入器 Guice.createInjector

public class MyAppTest {
    private static Injector injector;

    @BeforeClass
    public static void init() {
        injector = Guice.createInjector(new MyAppModule());
    }

    @Test
    public void testMyApp() {
        Application myApp = injector.getInstance(Application.class);
        myApp.work();
    }
}

参考1:JAVA轻量级IOC框架Guice - Leejk - 博客园

参考2:Guice 快速入门 - 腾讯云开发者社区-腾讯云

guice 官网地址:GitHub - google/guice: Guice (pronounced 'juice') is a lightweight dependency injection framework for Java 8 and above, brought to you by Google.

二、Jersey

Jersey 是一个 REST 框架,官网地址:Eclipse Jersey

基于 Jersey 的 REST 应用,可以运行在 Servlet 环境下(例如 Tomcat),也可以脱离 Servlet 环境,使用内置容器(例如 Jetty)。

注意:

jersey 1.X 使用的是 sun 的 com.sun.jersey

jersey 2.X 使用的是 glassfish 的 org.glassfish.jersey

使用内置容器为例(使用Jetty发布Jersey服务)

jersey 1.X

项目结构:

① 添加 maven 依赖

<dependency>
  <groupId>org.eclipse.jetty</groupId>
  <artifactId>jetty-server</artifactId>
  <version>9.3.8.v20160314</version>
</dependency>

<dependency>
  <groupId>org.eclipse.jetty</groupId>
  <artifactId>jetty-servlet</artifactId>
  <version>9.3.8.v20160314</version>
</dependency>

<dependency>
  <groupId>com.sun.jersey</groupId>
  <artifactId>jersey-server</artifactId>
  <version>1.19.1</version>
</dependency>

<dependency>
  <groupId>com.sun.jersey</groupId>
  <artifactId>jersey-servlet</artifactId>
  <version>1.19.1</version>
</dependency>

② 创建一个 JettyServer 类,用于配置 Jetty 环境:

package com.yuyu.jersey;

public class JettyServer {

    private void start() throws Exception {
        Server server = new Server(8080);
        ServletContextHandler context =
                new ServletContextHandler(ServletContextHandler.SESSIONS);
        context.setContextPath("/");
        server.setHandler(context);

        ServletHolder sh = new ServletHolder(ServletContainer.class);
        sh.setInitParameter(
                "com.sun.jersey.config.property.resourceConfigClass",
                "com.sun.jersey.api.core.PackagesResourceConfig");
        sh.setInitParameter(
                "com.sun.jersey.config.property.packages",
                "com.yuyu.jersey.api");
        context.addServlet(sh, "/*");
        server.start();
    }

    public void stop() throws Exception {

    }

    public static void main(String[] args) throws Exception {
        JettyServer server = new JettyServer();
        server.start();
    }
}

③ REST 服务的类(也称资源类,路径要和上面配置的保持一致)

package com.yuyu.jersey.api;

@Path("/welcome")
public class WelcomeResource {

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String sayHello() {
        return "Welcome to Jersey world";
    }
}

执行 main 方法,请求 http://localhost:8080/welcome,得到响应:



jersey 2.X

项目结构:

① 添加 maven 依赖

<dependency>
    <groupId>org.glassfish.jersey.containers</groupId>
    <artifactId>jersey-container-jetty-http</artifactId>
    <version>2.21</version>
</dependency>

② 创建一个 Application 类,用于设置发布环境:

package com.yuyu.jersey;

public class RestApplication extends ResourceConfig {
    public RestApplication(){
        this.packages("com.yuyu.jersey");
    }
}

· ResourceConfig 类继承了 Application 类,此类是 Jersey 中的基础类,用于定义一个 JAX-RS 应用的基础组件。

· 在 RestApplication 类的构造方法中,我们调用了 packages 方法注册了扫描资源类的基础包。


③ REST 服务的类(也称资源类)

package com.yuyu.jersey.test.demo;

@Path("hello")
public class HelloService {

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hi(){
        return "hello jersey";
    }
}

1. 在类上面添加了 @Path("hello"),代表资源根路径为 hello;

2. @GET 代表该方法接受 GET类型请求;

3. @Produces 代表该方法的响应类型为 text/plain;

4. 该方法返回 String,这个 String 值 Jersey 会自动按照 text/plain 格式输出。


④ 发布应用

package com.yuyu.jersey;

public class App {

    public static void main(String[] args) {
        JettyHttpContainerFactory.createServer(URI.create("http://localhost:8082/"), new RestApplication());
    }
}

执行 main 方法,请求 localhost:8082/hello,得到响应:

参考1:Jersey 开发RESTful(七)Jersey快速入门 - 简书

参考2:Jersey 开发RESTful(八)Jersey参数绑定 - 简书

参考3:Jetty + Jersey简单RESTful例子_飞飞好奇的博客-CSDN博客

jersey 官网:Eclipse Jersey

三、Jetty

Jetty 是一个开源的 servlet 容器,可以为JSP和Servlet提供运行时环境。

jetty 与 tomcat 区别:

(1) Jetty 比 Tomcat 架构更加简单。 jetty的所有组件都是基于 Handler 来实现,它的主要功能扩展都可以用 Handler 来实现。

(2) jetty 比较容易扩展第三方框架,所以也跟容易定制

(3) jetty更加轻量可以节省内存;

(4) tomcat 更加稳定、更加成熟。

参考:jetty、jetty原理、jetty与tomcat区别 - 知乎

四、Guice + Jersey + Jetty Demo

项目结构:

① 添加 maven 依赖

<dependency>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-server</artifactId>
    <version>9.3.24.v20180605</version>
</dependency>
<dependency>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-servlet</artifactId>
    <version>9.3.24.v20180605</version>
</dependency>

<dependency>
    <groupId>com.google.inject.extensions</groupId>
    <artifactId>guice-servlet</artifactId>
    <version>4.2.3</version>
</dependency>
<dependency>
    <groupId>com.google.inject</groupId>
    <artifactId>guice</artifactId>
    <version>4.2.3</version>
</dependency>

<dependency>
    <groupId>com.sun.jersey</groupId>
    <artifactId>jersey-server</artifactId>
    <version>1.19</version>
</dependency>
<dependency>
    <groupId>com.sun.jersey.contribs</groupId>
    <artifactId>jersey-guice</artifactId>
    <version>1.19</version>
</dependency>

② 创建一个资源 api 服务

@Path("/myTest")
public class ResourceTest {

    @GET
    @Path("/test")
    @Produces(MediaType.TEXT_PLAIN)
    public String testApi(){
        return "this is a test";
    }
}

③ 创建 WebServer 配置 servlet

public class WebServer {
    private final Server jetty;
    private final Connector connector;

    @Inject
    public WebServer(Server jetty, Connector connector) {
        this.jetty = jetty;
        this.connector = connector;
    }

    public void start() throws Exception {
        this.jetty.addConnector(connector);

        ServletHolder apiServletHolder = new ServletHolder(new GuiceContainer(Start.getInjector()));
        apiServletHolder.setInitParameter("com.sun.jersey.config.property.resourceConfigClass", "com.sun.jersey.api.core.PackagesResourceConfig");
        apiServletHolder.setInitParameter("com.sun.jersey.config.property.packages", "com.yuyu.demo.api");

        ServletContextHandler context = new ServletContextHandler();
        context.setContextPath("/");
        context.addServlet(apiServletHolder, "/*");

        this.jetty.setHandler(context);
        this.jetty.start();
    }

    public void stop() throws Exception {
        this.jetty.stop();
    }
}

④ 实现 ConnectorProvider 为 jetty 提供 http 连接

public class HttpConnectorProvider implements Provider<Connector> {
    private Server jetty;

    @Inject
    public HttpConnectorProvider(Server jetty) {
        this.jetty = jetty;
    }

    @Override
    public Connector get() {
        ServerConnector ret = new ServerConnector(this.jetty);
        ret.setName("test");
        ret.setHost("0.0.0.0");
        ret.setPort(8089);
        return ret;
    }
}

⑤ 创建 WebServerModule 绑定依赖

public class WebServerModule extends AbstractModule {
    private Server jetty;

    public WebServerModule() throws Exception {
        this.jetty = new Server();
    }

    @Override
    protected void configure() {
        bind(Server.class).in(Scopes.SINGLETON);
        bind(WebServer.class).in(Scopes.SINGLETON);
        bind(Connector.class).toProvider(HttpConnectorProvider.class);
    }
}

⑥ 创建 main 方法执行服务

public class Start {

    private static Injector injector;

    public static void main(String[] args) throws Exception {

        injector = Guice.createInjector(new WebServerModule());
        WebServer webServer = injector.getInstance(WebServer.class);
        webServer.start();
    }

    public static Injector getInjector() {
        return injector;
    }
}

执行结果:

参考:GitHub - sunnygleason/j4-minimal: Minimal web application example using Embedded Jetty, Jersey, Guice, and Jackson

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/82409.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[附源码]Python计算机毕业设计单位库房管理系统Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

老公下班要跟我学测试,35岁3娃全职宝妈的逆袭之路

马上35了&#xff0c;当了5年全职宝妈&#xff0c;看起来我应该是幸福的&#xff0c;公婆一直在帮忙带娃&#xff0c;老公也舍得给我花钱&#xff0c;愿意把钱全都交给我&#xff0c;在家里不用做饭&#xff0c;家务有人帮把手&#xff0c;主要就是带娃。我应该是幸福的&#x…

说说真实Java项目的开发流程,以及面试前的项目准备说辞

介绍项目是必不可少的Java面试环节&#xff0c;求职者需要借此证明自己真实Java项目的经验&#xff0c;如果再做的好的话&#xff0c;需要借此展开自己的亮点说辞。 不过之前如果只有学习项目经验&#xff0c;比如是自己跑通一个项目&#xff0c;或者是在培训班里通过一个Sprin…

Centos7:Postgresql 14安装

文章目录安装Server配置数据目录创建数据存储目录配置环境变量&#xff0c;数据目录Reload systemd初始化DB启动数据库安装模块包postgresql14-contribpostgresql14-devel安装Server sudo yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64…

(附源码)ssm高校实验室系统 毕业设计 800008

高校实验室管理系统 摘 要 随着社会的发展&#xff0c;社会的方方面面都在利用信息化时代的优势。互联网的优势和普及使得各种系统的开发成为必需。 本文以实际运用为开发背景&#xff0c;运用软件工程原理和开发方法&#xff0c;它主要是使用动态网页开发技术JSP&#xff0c;J…

前端js实现canvas压缩图片并上传

一. 上传前压缩图片的好处 可以减少用户的等待时间&#xff0c;提升使用体验&#xff0c;目前手机拍摄的图片文件大小一般在几 M 左右&#xff0c;文件直接上传时会有卡顿现象。可以减少服务端的存储空间。再次回去图片资源是也可以快速的加载。虽然目前阿里云的 oss 有相对应…

NPDP在国内有多少含金量?

产品经理国际资格认证&#xff0c;New Product Development Professional(NPDP)&#xff0c;由美国产品开发与管理协会&#xff08;PDMA&#xff09;所发起&#xff0c;是国际公认的唯一的新产品开发专业认证。是考察产品经理能力的证书。&#xff08;npdp产品经理资料文末&…

文本生成图像简述3--杂谈技术难点、研究意义、应用领域和目前的局限性

文本生成图像&#xff08;text-to-image&#xff09;指的是使用人工智能技术将文本转换为图像的过程&#xff0c;其可以根据给定文本生成符合描述的真实图像&#xff0c;其是多模态机器学习的任务之一&#xff0c;具有巨大的应用潜力&#xff0c;如视觉推理、图像编辑、视频游戏…

如何解决 Redis 数据倾斜、热点等问题

Redis 作为一门主流技术&#xff0c;应用场景非常多&#xff0c;很多大中小厂面试都列为重点考察内容 前几天有小伙伴学习时&#xff0c;遇到下面几个问题&#xff0c;来咨询 考虑到这些问题比较高频&#xff0c;工作中经常会遇到&#xff0c;这里写篇文章系统讲解下 问题描…

web网页设计期末课程大作业 HTML+CSS+JavaScript 美食餐饮文化主题网站设计 学生DW静态网页设计

&#x1f380; 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

关于vSphere HA Admission Control的讨论--2

上一期内容中预留的一些小问题首先做出回答&#xff1a; Q1&#xff1a;<若此时vCenter Server所在主机出现故障&#xff0c;vSphere HA是否能够正常完成故障响应&#xff1f;> A1&#xff1a;对于vSphere HA而言&#xff0c;在设计上采用主机通过FDM来管理HA的故障响应。…

天天刷 B 站,了解他们的评论系统是如何设计的吗?

今天给大家分享 B 站的评论系统的 组件化、平台化建设 通过持续演进架构设计&#xff0c;管理不断上升的系统复杂度&#xff0c;从而更好地满足各类用户的需求。 基础功能模块 评论的基础功能模块是相对稳定的。 1. 发布评论&#xff1a;支持无限盖楼回复。 2. 读取评论&…

DNS这个东西,你是真的了解了吗?

都说程序员是面向Google编程&#xff0c;殊不知当你输入 www.google.com 地址的时候&#xff0c;是否有想过&#xff0c;在回车的一瞬间浏览器如何将请求发送&#xff0c;如何到达目的地为你取得正确的数据。 遇到问题我们通常会打开浏览器&#xff0c;输入 www.google.com 回车…

EMQX+Prometheus+Grafana:MQTT 数据可视化监控实践

前言 作为一款全球下载量超千万的大规模分布式物联网 MQTT 服务器&#xff0c;最新发布的 EMQX 5.0 不仅全球首个达成单集群 1 亿 MQTT 连接支持&#xff0c;也是首个将 QUIC 引入 MQTT 的开创性产品。如今&#xff0c;EMQX 在各个行业为高可靠、高性能的物联网实时数据移动、…

阿里云服务器地域和可用区常见问题及官方资料解答

阿里云服务器同一地域分为多个可用区&#xff0c;不同地域的实例之间内网互不相通&#xff1b;选择靠近您客户的地域&#xff0c;可降低网络时延、提高您客户的访问速度。本文介绍阿里云地域和可用区的概念、选择指导、两者的关系以及阿里云支持的地域和可用区列表。 一.地域…

MySQL客户端的进阶操作

GreatSQL社区原创内容未经授权不得随意使用&#xff0c;转载请联系小编并注明来源。GreatSQL是MySQL的国产分支版本&#xff0c;使用上与MySQL一致。作者&#xff1a;土豆娃娃文章来源&#xff1a;社区投稿 引言 作为一个MySQL数据库从业者&#xff0c;我们最常用的工具就是my…

极米RS Pro 2值得买吗?极米科技这款4K投影真实体验怎么样?

2022电商的最后一场狂欢购物节“双十二”已到来&#xff0c;许多小伙伴想趁此次机会购置一些礼物给辛苦一年的自己和家人。但礼物怎么选&#xff1f;选什么&#xff1f;又成为了困扰大家的一大问题。要说送礼物&#xff0c;无论是自己还是家人&#xff0c;实用的家电是最不容易…

SRv6----控制平面

学习了SRv6----报文转发流程后&#xff0c;下一步学习SRv6的控制平面及SID是如何在SRv6网内传递学习的。 首先回顾一下回顾一下链路状态路由协议&#xff0c;基于Dijkstra SPF&#xff08;Shortest Path First&#xff0c;最短路径优先&#xff09;算法计算到达指定地址的最短路…

基于倾斜模型、地形DEM高程点的批量自动提取

我们在进行前期的规划分析的时候&#xff0c;总是离不开地形条件等限制性因素。这次分享一个小的操作技巧&#xff0c;利用倾斜模型、DEM数据批量自动提取高程点&#xff0c;用来计算坡度、坡向、填挖方、流域分析等等。 分享一下在图新地球工具软件基于倾斜模型、地形DEM如何…

华为数字化转型之道 实践篇 第六章 数字化重构业务运作模式【进行中】

第六章 数字化重构业务运作模式 数字化转型从企业业务战略出发,通过数字化手段来重构核心业务运作模式,以实现客户交易更简单、内部作业更高效、运营管理更便捷。 6.1 业务运作模式重构是数字化转型的核心 利用数字化技术创新业务运作模式,通过重构业务流程提升企业运作效…