- 浏览: 112293 次
- 性别:
- 来自: 济南
文章分类
最新评论
-
tuposky:
请教楼主,怎么在line 或 Circle 里面加一个titl ...
svg DOM的一些js操作 -
tuposky:
good...真全
svg DOM的一些js操作 -
温柔企鹅:
功力太浅,表示压力很大!
ExtJS中ajax回调函数,关于scope和createDelegate() -
jie523314:
miracletree 写道 好!太感谢你了
在ModalDialog中操作父窗口对象 -
miracletree:
好!太感谢你了
在ModalDialog中操作父窗口对象
装配Bean:即依赖注入
在Spring中,对象间的协作是通过IoC机制完成的。
反向控制也叫依赖注入(Dependency Injection,DI),简单来说就是将JavaBean需要的
对象通过配置文件加载进来。
Spring提供了两种装配Bean的容器,一是BeanFactoy,另一个是ApplicationContext。
两者做为容器,所有的Bean都应该通过容器装配,而容器也知道自己都装配了哪些Bean。
Bean装配实际上就是让容器知道程序中都有哪些Bean,可以通过以下两种方式实现:
配置文件(最为常用,体现了依赖注入DI的思想)
编程方式(写的过程中向BeanFactory去注册)
ApplicationContext与BeanFactory都是接口,ApplicationContext是由BeanFactory
接口扩展而来,它增强了BeanFactory的功能。
Bean容器能够加载的对象并不一定是严格遵循JavaBeans规范的Java类,任何可实例化的类都
可以通过Spring Bean容器加载进来。通常称这些类为POJO。
要记住,BeanFactory不仅仅只具备实例化Bean的功能,它还知道所有的Bean,可以配置和管理它们。
Spring给出一些BeanFactory的实现类,其中最为常用的是XmlBeanFactory。
1、通过文件系统
Resource res = new FileSystemResource("beans.xml");
XmlBeanFactory factory = new XmlBeanFactory(res);
2、通过类路径
ClassPathResource res = new ClassPathResource("beans.xml");
XmlBeanFactory factory = new XmlBeanFactory(res);
3、通过ApplicationContext加载
ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(new String[] {"applicationContext.xml", "applicationContext-part2.xml"} );
BeanFactory factory = (BeanFactory) appContext;
sping-frameword-1.2.7-with-dependencies中的dist里面是spring的包
将其中的spring.jar加入工程的类路径里面,下一步是写个javaBean
package bean ;
public class HelloBean
{
public HelloBean
{
System.out.println("init!");
}
private String msg ;
//加上getter和setter方法
};
public class Demo
{
public static void main(String[] args)
{
Resource res = new ClassPathResource("bean.xml") ;
//配置文件放在类路径的根路径下
BeanFactory factory = new XmlBeanFactory(res) ;
//在dist文件夹里面有spring-beans的dtd文档
HelloBean bean = (HelloBean)factory.getBean("hello") ;
//根据xml配置文件中的id号去找bean,然后从这个工厂中取出bean
System.out.println(bean.getMsg());
HelloBean bean1 = (HelloBean)factory.getBean("hello") ;
System.out.println(bean==bean1); //因为配置文件中的singleton设置为true,
//故是单例模式,所以两个bean肯定一样,所以打印true
//只有ApplicationContext才能实现bean的非延迟加载功能,所以要想让bean中的
//"init!"字符串在"before getbean!"字符串之前显示的话,那么首先必须得是单例模式,
//然后还得设置lazy-init="false",才可以做到,如果singleton="false"的话,是无法
//做到非延迟加载的!可以通过下面的代码来验证,看"before getbean!"和"init!"这两个
//字符串出现的先后顺序就一目了然了。
ApplicationContext factory = new ClassPathXmlApplicationContext("bean.xml");
System.out.println("before getbean!");
HelloBean bean2 = (HelloBean)factory.getBean("hello");
}
}
配置文件bean.xml:
将<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
拷贝进去……
<beans>
//singleton属性表明容器的bean是否使用单例模式……
//默认情况下,beanFactory就是延迟加载的
<bean id="hello" class="bean.HelloBean" singleton="true"
lazy-init="false">
<property name="msg">
<value>Hello,Spring!</value>
</property>
</bean>
</beans>
//上面的配置文件将属性的值注入到bean的属性中,这就是依赖注入的一个例子
//同时将那个javaBean注册到容器中
通常可以通过三种方式装配Bean
通过setter方法
通过构造函数
自动装配
其中,使用setter方法装配Bean是最为常用的。
如下代码的执行结果是什么?
FirstBean bean = (FirstBean)factory.getBean("my");
FirstBean bean1 = (FirstBean)factory.getBean("my");
System.out.println(bean==bean1);
结果依赖于bean元素的singleton属性,如果设置true,则以单例模式加载bean,
则永远指向同一个bean;反之则每次实例化一个。
也即在单例模式下,BeanFactory维护所有的bean
如果想让一个单例模式的bean被清理掉的话,不能简单的将bean置为null,而是必须使用
destroySingletons方法
还有一个destroyBean(String beanName,Object bean)
这两个方法都可以来垃圾回收单例模式中的bean
---------------------------------------------------------------
延迟加载:
如下代码执行的结果是什么?
System.out.println("before loading");
FirstBean bean = (FirstBean)factory.getBean("my");
System.out.println(“after loading”);
在bean的构造函数中,包含:
System.out.println(“bean init”);
结果依赖于bean的lazy-init属性,如果设置为true,则在第一次加载该bean时初始化;
否则在初始化容器时就加载所有bean。
延迟加载仅在bean单例模式下起作用。
-------------------------------------------------------------------------
初始化和清理:
Spring的初始化肯定是在依赖注入(属性设置)全部完成后才去做的。
框架提供的初始化方法肯定是先于我们自己定义的初始化方法的!比如,如果继承了
InitializingBean的话,会有一个这个接口提供的初始化方法,叫做afterPropertySet,
它的执行就是先于你定义的初始化方法的……
同理,DisposableBean接口中也定义了一个清理的方法,这个方法肯定也是先于你定义的
清理方法的!
建议使用你自己定义的初始化和清理方法,不要使用容器提供的,这样可以避免bean被污染!!!
在许多情况下,需要在对象加载后立即初始化资源,而在删除对象前先清理资源
在spring中,提供了两种方式实现初始化和清理工作。
通过设置bean的init-method和destroy-method指定初始与清理方法
通过实现InitializingBean及DisposableBean接口,由容器在加载与删除bean时自动调用。
//既然定义了一个init方法,所以可以在javaBean中设置下面的初始化方法:
public void init()
{
}
//同样销毁方法也可以类似的定义:
public void destroy()
{
}
//特别注意,如果你想运行上面自定义的destroy方法的话,你必须首先执行
factory.destroySingletons();
//否则不会去执行你上面自定义的destroy方法的!
原型bean在创建之后就脱离了factory的管理,所以呢,对于原型bean,只能初始化,而
不可以清理
<bean id="first" class="mybeans.FirstBean" init-method="init"
destroy-method="destroy" >
<property name="message">
<value>Hi,Rod Johnson</value>
</property>
</bean>
可以通过destroySingletons方法删除所有单例bean
原型bean在创建后即脱离BeanFactory的维护,所以只能调用初始化方法,而不能做清理工作。
===========================================================================
public class HelloBean implements BeanNameAware, BeanFactoryAware
{
private BeanFactory factory ;
private String name ;
public void setBeanName(String a)//由BeanNameAware继承来
{
this.name = a ;
}
//由BeanFactoryAware继承而来。
public void setBeanFactory(BeanFactory factory)
throws BeanException
{
this.factory = factory
}
}
-------------------------------------------------------
下面说说编程式加载Bean方式:
XmlBeanFactory提供两种编程方式加载Bean:
registerSingleton和registerBeanDefinition,前者不参与bean生命周期
后者参与bean的生命周期。
public static void main(String[] args)
{
Resource res = new ClassPathResource("bean.xml");
XmlBeanFactory factory = new XmlBeanFactory(res);
factory.registerSingleton("bb",new HelloBean());
HelloBean bean = (HelloBean)factory.getBean("bb");
System.out.println(bean.getMsg());
factory.destroySingletons();
}
如果使用BeanDefinition的话
public static void main(String[] args)
{
Resource res = new ClassPathResource("bean.xml");
XmlBeanFactory factory = new XmlBeanFactory(res);
RootBeanDefinition rbd = new RootBeanDefinition();
rbd.setBeanClass(HelloBean.class);
rbd.setInitMethodName("init");
//上面这句话告诉Spring自定义的方法名字叫做init,如果不写的话,自定义的
//初始化方法不会执行的。
/*
RootBeanDefinition rbd1 = new RootBeanDefinition(Integer.class);
ContructorArgumentValues cav = new ConstructorArgumentValues();
cav.addGenericArgumentValue("12");
rbd1.setConstructorArgumentValues(cav);
factory.registerBeanDefinition("aa",rbd1);
System.out.println(factory.getBean("aa"));
*/
factory.registerBeanDefinition("aa",rbd);
HelloBean bean = (HelloBean)factory.getBean("aa");
System.out.println(bean.getMsg());
factory.destroySingletons();
}
老师的关键代码如下:
XmlBeanFactory factory = new XmlBeanFactory(res);
RootBeanDefinition rbd = new RootBeanDefinition();
rbd.setBeanClass(HelloBean.class);
rbd.setInitMethodName("init");
RootBeanDefinition rbdi = new RootBeanDefinition(Integer.class);
ConstructorArgumentValues cav = new ConstructorArgumentValues();
cav.addGenericArgumentValue("12");
rbdi.setConstructorArgumentValues(cav);
=====================================================================
bean里面的属性是各式各样的,我们上面使用的实体类只是使用了String类型,根本没有考虑
其他的类型
bean装配方式:
通过Setter方法、通过构造函数、自动装配三种方法都可以达到装配Bean的目的。
其中使用setter方法装配Bean是最为常用的。
先说一下setter方法的装配:
setter方法可以装配基本类型、Bean类型、内部bean类型、集合类型、设置空值
所谓Bean类型属性是指这个属性类型是个javaBean,并且这个javaBean必须已经在Spring
中注册过了!
对于基本数据类型,
可以包括八种基本类型以及其包装类
<property name="" value="" />就可以了,不用在意具体类型,Spring会自动转换的。
装配基本类型:
包括八种基本类型及它们的包装类,还有String类型。
不必关心具体类型,spring可以通过反射机制了解到属性的类型信息
可以通过<property>的子元素<value>来设置基本类型的值,也可以通过其属性value来设置,
效果完全相同。
<bean id="first" class="mybeans.FirstBean" >
<property name="message">
<value>Hi, Rod Johnson</value>
</property>
<property name="age" value="1" />
//注意不能同时使用value子元素和value属性
</bean>
--------------------------------------------------------------------------
装配bean类型属性:
只有通过配置文件向容器注册的bean才能通过注入机制设置到其它bean的属性上。
使用<ref>子元素或ref属性设置
Spring即是通过这种方式建立起bean间的依赖关系,实现强大的bean管理功能。
举例说明:
BasicDataSource
引入包commons-dbcp、commons-pool以及commons-collections三个包引入
还有mysql的驱动程序
将BasicDataSource中的setter方法注入Spring中去。
在bean.xml中:
//将BasicDataSource中的setter方法中的对应值设置进去!
<beans>
<bean id="data" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///j2ee"/>
<property name="username" value="root" />
<property name="password" value="root" />
</bean>
<bean id="course" class="bean.CourseBean">
<property name="dataSource" ref="data"/>
//由于是bean,所以使用ref!
</bean>
</beans>
建立一个Bean,对应数据库中的一个表
public class CourseBean
{
private int id ;
private String name ;
private DataSource dataSource ;
//加入getter和setter方法
public void save()
{
}
}
然后就可以进行一下数据库的操作了……
在main函数中执行下面的代码:
---------------------------------------------------------------
Resource res = new ClassPathResource("bean.xml");
XmlBeanFactory factory = new XmlBeanFactory(res);
CourseBean course = (CourseBean)factory.getBean("course");
//由于数据源和courseBean之间的依赖关系已经通过配置文件给配置好了,所以这里
//只需要得到courseBean,就自然有了数据源的bean了。
course.setName("adsf");
course.save();
-----------------------------------------------------------------
所谓DAO就是既有值,又可以将这个值存入数据库的对象,也就是数据库访问对象
Data Access Object
所谓VO就是仅仅有值,也就是value object,值对象。
上面的这个course就是DAO了。
上面的save方法可以简单的写成下面的样子:
public void save()
{
try
{
Connection con = this.dataSource.getConnection();
String sql = "insert into courses (coursename,period)"+
"values(rtrim(?),rtrim(?))" ;
PreparedStatement pstmt = con.prepareStatement(sql) ;
pstmt.setString(1,this.coursename);
pstmt.setInt(2,this.period.intValue());
pstmt.executeUpdate();
}
catch (SQLException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
======================================================================
如果一个bean在使用前,其某个属性的值必须已经通过注入机制注入,spring可以协助检查这个属性
是否被初始化。
bean的属性dependency-check即用来实现这样的功能,其可选值包括
none --不检查
objects --仅检查bean类型
simple --仅检查基本类型(8种)和String类型
all --全检查
default --默认,不检查
此外,因为可能会调用其它对象的方法,有时一个对象在使用前必须要求另外一个对象已经初始化完成
这种依赖关系可以通过depends-on属性来实现,spring会保证在初始化当前对象前将depends-on
指定的对象也初始化出来。
如果依赖多个对象,使用逗号将它们的名字分开。
内部Bean
<bean id="outer" class="...">
<property name="target">
<bean class="com.mycompany.PersonImpl">
<property name="name">
<value>Tony</value>
</property>
</bean>
</property>
</bean>
----------------------------------------------------
Spring支持以下四种集合的装配:
<list>--java.util.List
<set>--java.util.Set
<map>--java.util.Map
<props>--java.util.Properties
list:
<property name="someList">
<list>
<value>someValue</value>
<ref bean="myDataSource"/>
<list>
<value>anyValue</value>
</list>
</list>
</property>
set:
<property name="someSet">
<set>
<value>just some string</value>
<ref bean="myDataSource"/>
</set>
</property>
map:
<property name="someMap">
<map>
<entry>
<key><value>yup an entry</value></key>
<value>just some string</value>
</entry>
<entry>
<key><value>yup a ref</value></key>
<ref bean="myDataSource"/>
</entry>
</map>
</property>
props:
<property name="people">
<props>
<prop key="HarryPotter">
The magic property
</prop>
<prop key="JerrySeinfeld">
The funny property
</prop>
</props>
</property>
==========================================================
==========================================================
如果属性没有setter方法的话,需要考虑使用构造方法装配pbean的属性,这就是
构造装配
一般在以下情况使用:
属性没有setter方法,是只读属性
属性只需要设置一次,以后就不会再更改
一般使用构造装配只装配少量属性
注意在构造装配下,构造函数中应该包含有需要装配的属性
比如:
<bean id="i" class="java.lang.Integer">
<constructor-arg value="23" />
</bean>
这就是利用构造函数将Integer注入到容器中去。
Integer i = (Integer)factory.getBean("i");
System.out.println(i);
-----------------------------------------------------
<bean id="first" class="mybeans.FirstBean">
<constructor-arg>
<value>http://www.sohu.com</value>
</constructor-arg>
<constructor-arg>
<value>http://localhost:8080</value>
</constructor-arg>
<property name="age" value="1" />
</bean>
多个参数时使用多个constructor-arg指定,出现次序决定了参数次序,或者使用index属性指定
======================================================
自动装配:
可以通过spring框架自动为bean装配属性。
自动装配只能装配bean类型,即取代ref元素。
使用自动装配只需在bean元素中加入属性autowire,自动装配可被手动装配覆盖。
也可以选择在beans中加入default-autowire属性,为所有bean设置默认自动装配。
“no“-不使用自动装配,spring推荐。
“byName”-依据名称或ID装配bean,如果没有找到,则不装配,可依赖dependency-check
属性检查是否装配。
“byType”-依据类型自动装配,如果存在两个以上同种类型,则抛出异常。
“constructor”-依据当前bean构造函数装配,查找与构造函数参数同类型bean
“autodetect”-自动检测,先通过constructor,再使用byType
Spring是不推荐使用自动装配的,首先是系统开销的问题,还有就是同名的设置可能会导致
意外的问题……
====================================================================
通过BeanFactory获取Bean与直接new一个Bean是完全不同的。
不相同的地方在于:从factory中得到的bean是被注入依赖关系的bean,而new出来的bean
则没有依赖关系,属性是空的。
通过BeanFactory获取的bean能将所有依赖注入到bean中,属性的值会依设置而定。
New出来的bean属性值必须主动设置。
在需要使用spring框架情况下,所有bean都应该由容器来管理。
===================================================================
单例和原型的问题:依赖于singleton参数,true为单例模式。
延迟加载:体现在整个容器初始化的时候立刻加载bean还是等到使用这个bean的时候才加载。
factory.getBean的时候就已经是开始使用bean了,并不一定要访问其中的属性
才算是使用。
只有ApplicationContext才能做到容器初始化的时候立刻加载bean,BeanFactory
是做不到的。
注册bean的时候,name属性是用的别名,id属性标明真名。name一般是在web开发里面去用,name
里面是可以包含一些特殊符号的,用于告诉开发者当前的属性代表什么具体的实际意思。
setter方法、构造函数和自动装配三种装配bean的方式
=====================================================================
ApplicationContext:
ApplicationContext与BeanFactory的作用相类似,都起到装配、管理Bean的作用。
不同的是,ApplicationContext在此基础上增强了BeanFactory的功能,这包括国际化、
加载资源、发布事件等等。
国际化的支持:
Spring提供了两个实现了MessageSource接口的类,它们都在
org.springframework.context.support包中:
ResourceBundleMessageSource使用JFC中标准的java.util.ResourceBundle来操作资源
ReloadableResourceBundleMessageSource 可以在不重启虚拟机的情况下重新加载资源。
ResourceBundleMessageSource是具体的类而且有setter方法,所以可以注入
根据setBasename,
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="bean.res" />
</bean>
千万注意一点,只要是资源包的话,id必须起名字为“messageSource”!!!!
这里还需要在bean包下面建立一个资源包res.properties,
在里面写上:
msg=Hello,{0}
public static void main(String[] args)
{
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("bean.xml");
String s = context.getMessage("msg",new Object[]{"Spring-Hibernate"},new Locale("zh"));
System.out.println(s);
}
这就打印出了“Hello,Spring-Hibernate”
------------------------------------------
假如有多个资源包呢?
比如我又在bean包里面建了一个ress.properties
m=M
那么
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>bean.res</value>
<value>bean.ress</value>
</list>
</property>
</bean>
--------------------------------------------------------
可以通过IOC机制加载资源,如
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename">
<value>springResource</value>
</property>
</bean>
或者
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>format</value>
<value>exceptions</value>
<value>windows</value>
</list>
</property>
</bean>
千万注意一点,只要是资源包的话,id必须起名字为“messageSource”!!!!
相关推荐
Spring、SpringMVC和Mybatis是Java开发中最常用的三大开源框架,它们的整合使用,通常被称为SSM框架。这个框架组合提供了完整的后端服务解决方案,包括依赖注入(DI)、面向切面编程(AOP)、模型-视图-控制器(MVC...
弃用了struts,用spring mvc框架做了几个项目,感觉都不错,而且使用了注解方式,可以省掉一大堆配置文件。本文主要介绍使用注解方式配置的spring mvc,之前写的spring3.0 mvc和rest小例子没有介绍到数据层的内容,...
Spring Integration + Spring WS 整合 在 Java 领域中,Spring Integration 和 Spring WS 是两个常用的框架,它们分别负责集成系统和 Web 服务。今天,我们将探讨如何将这两个框架整合在一起,实现一个完整的 Web ...
### Spring Boot、Spring Cloud、Spring Boot Alibaba及其配套组件版本关系详解 #### 一、引言 随着微服务架构的流行,Spring Boot、Spring Cloud、Spring Boot Alibaba等技术栈成为构建现代分布式系统的基石。然而...
包含spring 3.0.5的所有jar文件: org.springframework.aop-3.0.5.RELEASE.jar org.springframework.asm-3.0.5.RELEASE.jar org.springframework.aspects-3.0.5.RELEASE.jar org.springframework.beans-3.0.5.RELEASE...
Spring Batch是一个轻量级的,完全面向Spring的批处理框架,可以应用于企业级大量的数据处理系统。Spring Batch以POJO和大家熟知的Spring框架为基础,使开发者更容易的访问和利用企业级服务。Spring Batch可以提供...
Spring框架是Java应用程序开发中的一个核心组件,它提供了一个丰富的IOC(Inversion of Control,控制反转)和AOP(Aspect-Oriented Programming,面向切面编程)功能,使得开发者能够更方便地管理对象和实现模块化...
在Java开发领域,Spring Boot和Spring Batch的整合是构建高效批处理系统的一种常见方式。Spring Boot以其简洁的配置和快速的启动能力深受开发者喜爱,而Spring Batch作为Spring框架的一部分,专注于批量处理任务,...
在构建分布式系统时,Spring Cloud Gateway 作为微服务架构中的边缘服务或 API 网关,扮演着至关重要的角色。它负责路由请求到相应的微服务,并可以提供过滤器功能,如限流、熔断等。而Spring Security 则是 Java ...
spring3.1官方所有的jar包 org.springframework.aop-3.1.RELEASE.jar org.springframework.asm-3.1.RELEASE.jar org.springframework.aspects-3.1.RELEASE.jar org.springframework.beans-3.1.RELEASE.jar org....
这篇文章将教你快速地上手使用 Spring 框架. 如果你手上有一本《Spring in Action》, 那么你最好从第三部分"Spring 在 Web 层的应用--建立 Web 层"开始看, 否则那将是一场恶梦! 首先, 我需要在你心里建立起 Spring...
Getting started with Spring Framework (4th Edition) is a hands-on guide to begin developing applications using Spring Framework 5. The examples (consisting of 88 sample projects) that accompany this ...
Spring 详细讲解 Spring 是一个功能强大且功能齐全的 Java 应用程序框架,提供了一个通用的基础结构来支持开发企业级应用程序。 Spring 框架的核心是控制反转(IoC)和依赖注入(DI)模式,它们使得应用程序更加...
介绍一个基于Spring Boot 3.0、Spring Cloud 2022 & Alibaba的微服务RBAC权限管理系统。该系统可以实现微服务RBAC权限管理,通过RBAC权限管理机制对用户访问系统的权限进行限制,从而提高系统的安全性和可用性。同时...
项目原型:Struts2.3.16 + Spring4.1.1 + Hibernate4.3.6 二、 项目目的: 整合使用最新版本的三大框架(即Struts2、Spring4和Hibernate4),搭建项目架构原型。 项目架构原型:Struts2.3.16 + Spring4.1.1 + ...
Spring Cloud和Spring Boot是两个非常重要的Java开发框架,它们在微服务架构中扮演着核心角色。Spring Boot简化了创建独立的、生产级别的基于Spring的应用程序的过程,而Spring Cloud则为开发者提供了快速构建分布式...
《Spring AI Core 0.8.1:开启人工智能之旅》 在现代软件开发领域,Spring框架以其强大的功能和灵活性,已经成为Java开发中的首选框架之一。而Spring AI Core则是Spring生态系统中专门为人工智能(AI)和机器学习...
《Spring技术内幕:深入解析Spring架构与设计原理(第2版)》从源代码的角度对Spring的内核和各个主要功能模块的架构、设计和实现原理进行了深入剖析。你不仅能从本书中参透Spring框架的出色架构和设计思想,还能从...
Spring 框架是 Java 开发中的一个核心组件,它为构建企业级应用程序提供了全面的编程和配置模型。Spring 4.3.14 是该框架的最后一个4.x系列正式版,发布于2018年2月24日。这个版本在Spring 5.0发布之前提供了一个...
在IT行业中,Spring框架是Java应用开发中的一个关键组件,它提供了一整套服务来简化企业级应用的构建。RabbitMQ则是一个流行的开源消息队列系统,它基于AMQP(Advanced Message Queuing Protocol)协议,用于高效地...