JAVA EE初阶 - 预备知识(二)

一、Java EE主要组成部分

核心 API

  • Servlet : Servlet 是 Java EE 中用于处理客户端请求和生成动态网页的组件。它运行在服务器端,能够接收客户端的 HTTP 请求,进行相应的处理,并将处理结果返回给客户端。例如,一个用户登录页面的表单数据可以通过 Servlet 接收和验证。【前文已介绍】
  • JSP(JavaServer Pages) :JSP 是一种动态网页技术,它允许在 HTML 页面中嵌入 Java 代码。JSP 页面在服务器端被编译成 Servlet 后执行,最终生成 HTML 页面返回给客户端。使用 JSP 可以方便地将业务逻辑和页面展示分离,提高开发效率。【前文已介绍】
  • EJB(Enterprise JavaBeans) :EJB 是 Java EE 中用于开发企业级业务组件的规范。它提供了分布式对象模型,支持事务管理、安全性、并发控制等功能。EJB 主要分为会话 Bean(用于处理业务逻辑)、实体 Bean(用于表示数据库中的数据)和消息驱动 Bean(用于异步消息处理)。
  • JPA(Java Persistence API) :JPA 是 Java EE 中用于对象 - 关系映射(ORM)的规范。它允许开发者使用面向对象的方式来操作数据库,而不需要编写复杂的 SQL 语句。通过 JPA,开发者可以将 Java 对象持久化到数据库中,或者从数据库中查询数据并映射为 Java 对象。
  • JMS(Java Message Service) :JMS 是 Java EE 中用于实现消息传递的规范。它支持异步通信模式,允许不同的应用程序之间通过消息进行通信。例如,一个订单处理系统可以通过 JMS 将订单信息发送给库存管理系统,实现系统之间的解耦。
  • JAAS(Java Authentication and Authorization Service) :JAAS 是 Java EE 中用于实现身份验证和授权的规范。它提供了一个可插拔的安全框架,允许开发者根据不同的安全需求选择合适的认证和授权机制。例如,在一个企业级的 Web 应用中,可以使用 JAAS 来验证用户的身份,并根据用户的角色授予不同的访问权限。

应用服务器

  • Java EE 应用需要运行在应用服务器上,常见的应用服务器有 Oracle WebLogic Server、IBM WebSphere Application Server、Red Hat JBoss EAP 等。应用服务器提供了 Java EE 规范的实现,负责管理应用程序的生命周期、提供事务管理、安全管理等服务。

二、特点

  • 分布式计算 :Java EE 支持分布式应用的开发,允许应用程序的不同组件运行在不同的服务器上,通过网络进行通信和协作。这样可以提高应用程序的可扩展性和性能,同时也便于进行负载均衡和容错处理。
  • 事务管理 :Java EE 提供了强大的事务管理机制,确保在多个数据库操作或业务逻辑执行过程中,要么全部成功,要么全部失败。例如,在一个银行转账系统中,从一个账户扣除金额和向另一个账户添加金额的操作必须作为一个原子事务来处理,以保证数据的一致性。
  • 安全性:Java EE 提供了多层次的安全机制,包括身份验证、授权、数据加密等。开发者可以根据应用程序的安全需求,选择合适的安全策略,保护企业数据的安全。
  • 可扩展性:Java EE 应用程序可以很容易地进行扩展,通过添加更多的服务器或资源来处理增加的用户请求。同时,Java EE 规范的模块化设计也使得开发者可以根据需要选择和集成不同的组件,提高应用程序的灵活性和可维护性。

Java EE 支持分布式应用开发,允许应用程序的不同组件运行在不同服务器上并通过网络通信协作,这一特性为构建大规模、高性能、可扩展的企业级应用提供了强大支持,以下从概念、实现方式、优势和应用场景几方面详细解释:

概念理解

在传统的单体应用中,应用程序的所有功能模块都运行在同一台服务器上。而分布式应用则将一个大型应用拆分成多个相对独立的组件(如服务模块、数据存储模块等),这些组件可以部署在不同的服务器上,通过网络进行交互和协同工作。Java EE 提供了一系列的技术和规范,使得开发者能够方便地构建和管理这样的分布式应用。

实现方式

  • 远程方法调用(RMI,Remote Method Invocation) :RMI 是 Java EE 中实现分布式对象通信的一种机制。它允许一个 Java 虚拟机(JVM)上的对象调用另一个 JVM 上的对象的方法,就像调用本地对象的方法一样。例如,在一个分布式的电商系统中,订单服务模块可以通过 RMI 调用库存服务模块的方法来检查商品库存。
java 复制代码
// 定义远程接口
import java.rmi.Remote;
import java.rmi.RemoteException;

public interface InventoryService extends Remote {
    int checkStock(String productId) throws RemoteException;
}

// 实现远程接口
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class InventoryServiceImpl extends UnicastRemoteObject implements InventoryService {
    protected InventoryServiceImpl() throws RemoteException {
        super();
    }

    @Override
    public int checkStock(String productId) throws RemoteException {
        // 实际的库存检查逻辑
        return 10; 
    }
}

// 客户端调用
import java.rmi.Naming;

public class OrderServiceClient {
    public static void main(String[] args) {
        try {
            InventoryService inventoryService = (InventoryService) Naming.lookup("rmi://localhost:1099/InventoryService");
            int stock = inventoryService.checkStock("P001");
            System.out.println("商品库存: " + stock);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • 企业 JavaBeans(EJB):EJB 是 Java EE 中用于开发企业级业务组件的规范,支持分布式调用。EJB 容器负责管理 EJB 组件的生命周期、事务处理和安全管理等,并且提供了远程调用的功能。不同服务器上的 EJB 组件可以通过网络进行通信和协作。
  • 消息驱动 Bean(MDB) :MDB 是 EJB 的一种特殊类型,用于处理异步消息。它可以接收来自消息队列(如 JMS 队列)的消息,并进行相应的处理。通过消息队列,不同服务器上的组件可以实现异步通信和协作。例如,一个订单处理组件可以将订单消息发送到消息队列,另一个库存更新组件从队列中接收消息并更新库存。

优势

  • 可扩展性:通过将应用程序的不同组件分布在多个服务器上,可以根据业务需求灵活地扩展某个组件的资源。例如,当电商系统的订单量大幅增加时,可以增加订单服务模块所在服务器的数量,而不需要对整个应用进行大规模的升级。
  • 高性能:分布式应用可以充分利用多台服务器的计算资源,提高应用程序的处理能力。不同的组件可以并行处理任务,减少了单个服务器的负载,从而提高了系统的响应速度和吞吐量。
  • 容错性:如果某个服务器出现故障,其他服务器上的组件仍然可以继续工作,不会导致整个应用程序崩溃。例如,在一个分布式数据库系统中,如果一台数据库服务器出现故障,其他数据库服务器可以继续提供服务,保证了数据的可用性。
  • 资源利用率:可以根据不同组件的需求,选择合适的服务器硬件配置。例如,对于计算密集型的组件,可以选择配置高性能的 CPU 和内存;对于存储密集型的组件,可以选择大容量的磁盘存储。
应用场景
  • 大型企业级应用:如企业资源规划(ERP)系统、客户关系管理(CRM)系统等,这些系统通常需要处理大量的业务数据和复杂的业务逻辑,分布式应用的架构可以满足其高并发、高可扩展性的需求。
  • 互联网应用:如电商平台、社交网络等,这些应用需要面对大量的用户访问和数据交互,分布式应用可以通过负载均衡和分布式存储等技术,提高系统的性能和可用性。
  • 云计算应用:在云计算环境中,分布式应用可以充分利用云平台的弹性计算资源,根据业务需求动态调整资源配置,降低运营成本。

三、Java EE 中的消息驱动 Bean(Message Driven Bean)

消息驱动 Bean(Message Driven Bean,MDB)是 Java EE(现 Jakarta EE)平台中的一种企业级组件,它结合了 Java 消息服务(JMS)的异步消息传递机制和 EJB(Enterprise JavaBeans)容器的管理功能,主要用于处理异步消息。以下为你详细介绍:

基本概念

  • 异步消息处理 :传统的应用程序调用通常是同步的,即调用方必须等待被调用方完成操作后才能继续执行后续代码。而 MDB 采用异步消息处理方式,发送方将消息发送到消息队列后,无需等待接收方处理消息,就可以继续执行其他任务。接收方(MDB)在消息到达队列时会自动触发处理逻辑。(实现消息传递的异步)
  • 解耦通信 :MDB 使得消息的发送者和接收者之间实现了松耦合。发送者只需将消息发送到指定的消息队列,而无需关心谁来处理这些消息以及如何处理。接收者(MDB)也只需关注从消息队列中接收消息并进行处理,不需要知道消息的发送者是谁。
工作原理
  1. 消息发送:消息生产者(可以是另一个 EJB、Servlet 或其他 Java 程序)将消息发送到 JMS 消息队列(如队列或主题)。消息可以是文本消息、对象消息等不同类型。
  2. 消息监听:MDB 会监听特定的 JMS 消息队列。当有新消息到达队列时,EJB 容器会自动创建或选择一个 MDB 实例来处理该消息。
  3. 消息处理 :MDB 接收到消息后,会调用其预定义的消息处理方法(通常是 onMessage 方法)对消息进行处理。处理逻辑可以包括业务逻辑处理、数据库操作、调用其他服务等。
  4. 事务管理 :EJB 容器负责管理 MDB 的事务。如果消息处理过程中出现异常,容器可以根据事务配置进行回滚操作,确保数据的一致性。

代码示例

以下是一个简单的 MDB 示例,用于处理 JMS 文本消息:

java 复制代码
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

// 定义 MDB 并指定监听的消息队列和连接工厂
@MessageDriven(activationConfig = {
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
    @ActivationConfigProperty(propertyName = "destination", propertyValue = "java:/jms/queue/MyQueue")
})
public class MyMessageDrivenBean implements MessageListener {

    @Override
    public void onMessage(Message message) {
        if (message instanceof TextMessage) {
            try {
                TextMessage textMessage = (TextMessage) message;
                String text = textMessage.getText();
                System.out.println("接收到消息: " + text);
                // 这里可以添加具体的业务处理逻辑
            } catch (JMSException e) {
                e.printStackTrace();
            }
        }
    }
}

优点

  • 提高系统性能和响应速度:由于采用异步消息处理方式,发送方无需等待消息处理完成,从而提高了系统的并发处理能力和响应速度。例如,在一个电商系统中,用户下单后,系统可以立即将订单消息发送到消息队列,然后返回给用户下单成功的提示,而订单的后续处理(如库存扣减、订单状态更新等)由 MDB 异步处理。
  • 增强系统的可扩展性和灵活性:MDB 使得系统的各个组件之间实现了松耦合,方便对系统进行扩展和维护。可以根据业务需求增加或减少 MDB 的实例数量,也可以修改 MDB 的处理逻辑而不影响其他组件。
  • 实现系统的异步通信和集成:MDB 可以与不同的系统进行集成,通过消息队列实现异步通信。例如,一个企业的内部系统可以通过 MDB 与外部的物流系统、支付系统进行集成,实现订单信息的传递和处理。
应用场景
  • 异步任务处理:如邮件发送、文件生成、数据备份等任务可以通过 MDB 进行异步处理,避免阻塞主线程,提高系统的性能。
  • 系统集成:在企业级应用中,不同的子系统之间可以通过 MDB 进行集成,实现数据的传递和业务的协同处理。例如,一个企业的 ERP 系统和 CRM 系统可以通过消息队列和 MDB 进行数据同步。
  • 事件驱动的系统:在一些事件驱动的系统中,MDB 可以用于监听和处理各种事件消息,触发相应的业务逻辑。例如,在一个物联网系统中,MDB 可以监听传感器发送的消息,根据消息内容进行数据分析和处理。

四、组件

在软件开发领域,组件(Component)是一个具有特定功能、相对独立且可复用的软件模块或程序单元。它是构建复杂软件系统的基础元素,以下从不同角度为你详细介绍:

组件的特性

  • 独立性:组件具有明确的边界和接口,与其他组件之间的耦合度较低。这意味着一个组件可以在不影响其他组件的情况下进行开发、测试和部署。例如,在一个电商系统中,商品展示组件、购物车组件和订单处理组件都可以独立开发和维护。
  • 功能性:每个组件都有特定的功能,它封装了实现该功能所需的代码和数据。例如,一个日期处理组件可能包含日期格式化、日期计算等功能。
  • 可复用性:组件可以在不同的软件项目或同一项目的不同部分中重复使用,提高了开发效率,减少了代码的重复编写。例如,日志记录组件可以被多个不同的应用程序使用。
  • 可组合性:多个组件可以组合在一起,形成更复杂的系统或功能。通过组件的组合,可以快速构建出满足不同需求的软件系统。例如,将用户认证组件、商品管理组件和订单管理组件组合在一起,可以构建出一个完整的电商系统。

常见的组件类型

  • 图形用户界面(GUI)组件:用于构建软件的用户界面,如按钮、文本框、下拉列表等。这些组件通常提供了可视化的交互元素,方便用户与软件进行交互。例如,在一个桌面应用程序中,使用按钮组件可以实现用户的点击操作,使用文本框组件可以让用户输入信息。
  • 业务逻辑组件:封装了特定的业务规则和处理逻辑,如订单处理、库存管理、用户认证等。这些组件是软件系统的核心,负责实现业务功能。例如,在一个银行系统中,转账业务逻辑组件负责处理用户的转账请求,包括验证账户信息、检查余额、更新账户余额等操作。
  • 数据访问组件:用于与数据库或其他数据存储系统进行交互,实现数据的读取、写入、更新和删除等操作。例如,在一个企业资源规划(ERP)系统中,数据访问组件可以从数据库中获取员工信息、订单信息等。
  • 通信组件:负责实现不同系统或组件之间的通信,如网络通信、消息传递等。例如,在一个分布式系统中,通信组件可以使用套接字(Socket)或远程方法调用(RMI)等技术实现不同服务器之间的通信。

组件在不同技术栈中的体现

  • Java 中的组件
    • JavaBean:是一种符合特定规范的 Java 类,通常用于封装数据和提供简单的业务逻辑。JavaBean 具有无参构造函数,并且通过 getter 和 setter 方法来访问其属性。例如,一个用户信息的 JavaBean 可以包含用户名、密码、邮箱等属性。
    • Enterprise JavaBeans(EJB):是 Java EE 平台中用于开发企业级应用的组件规范,包括会话 Bean、实体 Bean 和消息驱动 Bean 等。EJB 提供了事务管理、安全性、分布式计算等功能,适用于构建大型、分布式的企业级应用。
    • Servlet 和 JSP:Servlet 是 Java 中用于处理客户端请求和生成动态网页的组件,JSP(JavaServer Pages)则是一种基于 Servlet 的动态网页技术,允许在 HTML 页面中嵌入 Java 代码。它们通常用于构建 Web 应用程序。
  • .NET 中的组件
    • Windows 窗体控件:用于创建 Windows 桌面应用程序的用户界面,如按钮、文本框、列表框等。这些控件可以通过拖放的方式添加到窗体上,并可以通过属性窗口进行配置。
    • ASP.NET Web 控件 :用于构建 Web 应用程序的用户界面,如按钮、文本框、GridView 等。ASP.NET Web 控件提供了丰富的功能和事件处理机制,方便开发人员快速构建交互式的 Web 页面。
    • .NET 类库中的组件:.NET 框架提供了大量的类库,其中包含了各种功能组件,如文件操作组件、网络通信组件、数据访问组件等。开发人员可以直接使用这些组件来实现特定的功能。

组件化开发的优势

  • 提高开发效率:通过复用已有的组件,可以减少代码的编写量,缩短开发周期。开发人员可以将更多的精力放在组件的组合和业务逻辑的实现上。
  • 便于维护和升级:由于组件具有独立性,当某个组件出现问题或需要进行功能升级时,只需要对该组件进行修改,而不会影响其他组件。这降低了维护和升级的难度和风险。
  • 提高软件质量:组件经过多次使用和测试,其稳定性和可靠性得到了验证。通过使用高质量的组件,可以提高整个软件系统的质量。
  • 促进团队协作:组件化开发使得开发团队可以分工协作,不同的开发人员负责不同的组件开发。这样可以提高团队的开发效率,同时也便于团队成员之间的沟通和协调。

五、容器

在计算机领域,"容器" 有不同层面的含义,常见于软件开发、云计算等场景,下面为你详细介绍不同语境下容器的概念:

软件开发中的容器

Java EE 容器
  • 定义 :在 Java EE(现 Jakarta EE)开发中,容器是一种管理 Java EE 组件(如 Servlet、JSP、EJB 等)生命周期的运行环境。它提供了一系列服务,使得组件可以专注于业务逻辑的实现,而无需关心底层的系统资源管理、事务处理、安全管理等问题。
  • 类型及作用
    • Servlet 容器:如 Apache Tomcat、Jetty 等,负责管理 Servlet 和 JSP 组件。它接收客户端的 HTTP 请求,将请求分发到相应的 Servlet 进行处理,并将处理结果返回给客户端。同时,Servlet 容器还负责 Servlet 的生命周期管理,包括实例化、初始化、服务和销毁等操作。
    • EJB 容器:如 Oracle WebLogic Server、IBM WebSphere Application Server 等,用于管理 EJB 组件。EJB 容器提供了事务管理、安全性、并发控制等服务,使得 EJB 可以在分布式环境中高效、安全地运行。
  • 优势
    • 简化开发:开发者只需关注业务逻辑的实现,容器会自动处理许多底层的技术细节,降低了开发难度。
    • 提高可移植性:遵循 Java EE 规范开发的组件可以在不同的容器中运行,提高了应用程序的可移植性。
其他编程语言中的容器

在其他编程语言中也有类似的概念。例如,在 Python 的 Django 和 Flask 框架中,框架本身可以看作是一种轻量级的容器,它管理着视图函数、路由等组件的生命周期,处理请求和响应,为开发者提供了便捷的 Web 开发环境。

云计算中的容器

Docker 容器
  • 定义:Docker 是一种开源的容器化平台,Docker 容器是基于 Docker 引擎创建的轻量级、可移植的独立运行环境。它将应用程序及其依赖项打包成一个独立的容器镜像,这个镜像包含了运行应用程序所需的所有文件、库和配置信息。
  • 工作原理
    • 镜像构建:开发者使用 Dockerfile 定义应用程序的构建步骤,包括基础镜像的选择、依赖项的安装、应用程序代码的复制等。然后使用 Docker 命令将 Dockerfile 构建成一个镜像。
    • 容器创建和运行:基于镜像可以创建一个或多个容器实例。每个容器都是相互隔离的,拥有自己的文件系统、进程空间等。容器可以在不同的 Docker 主机上运行,实现了应用程序的快速部署和迁移。
  • 优势
    • 资源利用率高:容器共享主机的操作系统内核,相比于传统的虚拟机,占用的系统资源更少,可以在同一台主机上运行更多的容器。
    • 快速部署和启动:容器的启动速度非常快,通常只需要几秒钟,大大缩短了应用程序的部署时间。
    • 环境一致性:容器将应用程序及其依赖项打包在一起,确保了应用程序在不同环境中的一致性,避免了 "在我机器上能运行,在你机器上不行" 的问题。
Kubernetes 与容器编排

Kubernetes 是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。它可以管理多个 Docker 容器,实现容器的自动调度、负载均衡、故障恢复等功能。例如,当某个容器出现故障时,Kubernetes 可以自动重启该容器或创建一个新的容器实例来替换它。

操作系统层面的容器

Linux 容器(LXC)

Linux 容器是一种操作系统级的虚拟化技术,它允许在一个主机上创建多个相互隔离的用户空间实例,每个实例就是一个容器。LXC 利用 Linux 内核的 cgroups(控制组)和 namespaces(命名空间)机制实现资源隔离和限制。与 Docker 容器相比,LXC 更加底层,提供了更多的灵活性和控制能力。

总结

无论是软件开发中的容器还是云计算中的容器,其核心思想都是将应用程序及其依赖项进行封装和隔离,提供一个独立的运行环境,从而提高开发效率、资源利用率和应用程序的可移植性。不同类型的容器在不同的场景中发挥着重要作用,开发者可以根据具体需求选择合适的容器技术。

六、消息传递的同步和异步

同步消息和异步消息是在计算机通信和软件开发中用于描述消息传递方式的两种重要概念,下面将从定义、工作原理、优缺点以及应用场景等方面详细介绍这两种消息传递方式。

同步消息

定义

同步消息是指发送方在发送消息后,会一直等待接收方处理完消息并返回响应,在这个等待期间,发送方不能进行其他操作,处于阻塞状态,直到收到响应后才会继续执行后续的代码或任务。

工作原理
  • 发送方发起消息请求。
  • 接收方接收到消息后开始处理。
  • 发送方一直等待,直到接收方处理完成并返回响应。
  • 发送方收到响应后,解除阻塞状态,继续执行后续操作。
代码示例(Java)
java 复制代码
import java.rmi.Naming;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

// 定义远程接口
interface RemoteService extends Remote {
    String processMessage(String message) throws RemoteException;
}

// 实现远程接口
class RemoteServiceImpl extends UnicastRemoteObject implements RemoteService {
    protected RemoteServiceImpl() throws RemoteException {
        super();
    }

    @Override
    public String processMessage(String message) throws RemoteException {
        try {
            // 模拟处理消息的耗时操作
            Thread.sleep(2000); 
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "处理结果: " + message;
    }
}

// 客户端代码
public class SyncMessageClient {
    public static void main(String[] args) {
        try {
            RemoteService service = (RemoteService) Naming.lookup("rmi://localhost:1099/RemoteService");
            System.out.println("发送消息并等待响应...");
            // 同步调用,会阻塞直到收到响应
            String response = service.processMessage("Hello"); 
            System.out.println("收到响应: " + response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
优缺点
  • 优点
    • 实现简单,逻辑清晰,易于理解和调试。
    • 可以确保消息处理的顺序性和一致性,因为发送方会等待接收方处理完成。
  • 缺点
    • 效率较低,因为发送方在等待响应期间处于阻塞状态,无法进行其他操作,可能会导致系统的吞吐量下降。
    • 容易造成系统的耦合度增加,因为发送方和接收方的执行流程紧密关联。
应用场景
  • 对数据一致性要求较高的场景,如银行转账、数据库事务操作等,需要确保操作的原子性和顺序性。
  • 简单的请求 - 响应交互场景,如客户端向服务器请求数据,服务器返回查询结果。

异步消息

定义

异步消息是指发送方在发送消息后,不会等待接收方处理消息和返回响应,而是继续执行后续的代码或任务。接收方在接收到消息后,会独立地进行处理,并在处理完成后可以选择以某种方式通知发送方。

工作原理
  • 发送方将消息发送到消息队列或其他中间件。
  • 发送方继续执行后续操作,不等待消息处理结果。
  • 接收方从消息队列中获取消息并进行处理。
  • 处理完成后,接收方可以通过回调函数、消息通知等方式将结果反馈给发送方(可选)。
代码示例(Java 使用 JMS)
java 复制代码
import javax.jms.*;
import javax.naming.InitialContext;
import javax.naming.NamingException;

// 消息发送者
public class AsyncMessageSender {
    public static void main(String[] args) {
        try {
            InitialContext context = new InitialContext();
            ConnectionFactory factory = (ConnectionFactory) context.lookup("ConnectionFactory");
            Destination destination = (Destination) context.lookup("queue/MyQueue");

            Connection connection = factory.createConnection();
            connection.start();

            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            MessageProducer producer = session.createProducer(destination);

            TextMessage message = session.createTextMessage("Hello, asynchronous message!");
            producer.send(message);
            System.out.println("消息已发送,继续执行其他任务...");

            session.close();
            connection.close();
        } catch (NamingException | JMSException e) {
            e.printStackTrace();
        }
    }
}

// 消息接收者
public class AsyncMessageReceiver implements MessageListener {
    @Override
    public void onMessage(Message message) {
        if (message instanceof TextMessage) {
            try {
                TextMessage textMessage = (TextMessage) message;
                System.out.println("收到消息: " + textMessage.getText());
            } catch (JMSException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        try {
            InitialContext context = new InitialContext();
            ConnectionFactory factory = (ConnectionFactory) context.lookup("ConnectionFactory");
            Destination destination = (Destination) context.lookup("queue/MyQueue");

            Connection connection = factory.createConnection();
            connection.start();

            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            MessageConsumer consumer = session.createConsumer(destination);
            consumer.setMessageListener(new AsyncMessageReceiver());

            System.out.println("等待消息...");
            // 保持程序运行以接收消息
            Thread.sleep(Long.MAX_VALUE); 
        } catch (NamingException | JMSException | InterruptedException e) {
            e.printStackTrace();
        }
    }
}
优缺点
  • 优点
    • 提高系统的并发处理能力和响应速度,因为发送方不需要等待接收方处理消息,可以继续执行其他任务。
    • 降低系统的耦合度,发送方和接收方的执行流程相对独立,便于系统的扩展和维护。
  • 缺点
    • 实现复杂度较高,需要处理消息队列的管理、消息的丢失和重复等问题。
    • 消息处理的顺序性和一致性较难保证,需要额外的机制来处理。
应用场景
  • 高并发的系统,如电商平台的订单处理、消息推送系统等,需要快速响应用户请求,提高系统的吞吐量。
  • 分布式系统中不同组件之间的通信,如微服务架构中各个服务之间的交互,通过异步消息可以实现服务的解耦和异步处理。
  • 对实时性要求不高的任务,如日志记录、数据备份等,可以通过异步消息将任务放入队列中,在后台进行处理。
相关推荐
西岸行者6 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意6 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码6 天前
嵌入式学习路线
学习
毛小茛6 天前
计算机系统概论——校验码
学习
babe小鑫6 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms6 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下6 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。6 天前
2026.2.25监控学习
学习
im_AMBER6 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J6 天前
从“Hello World“ 开始 C++
c语言·c++·学习