-
bus
2013-08-21 11:15:571.bus定义 总线是不同IC器件之间相互通讯的通道;在计算机中,一个总线就是处理器与一个或多个不同外设之间的通讯通道;为了设备模型的目的,所有的设备都通过总线相互连接,甚至当它是一个内部的虚拟总线(如,platform..."ls" 命令的 "-F" 命令为所列出的每个文件使用后缀来显示文件的类型,后缀 "/" 表示列出的是目录,后缀 "@" 表示列出的是符号链接文件。
1.bus定义
总线是不同IC器件之间相互通讯的通道;在计算机中,一个总线就是处理器与一个或多个不同外设之间的通讯通道;为了设备模型的目的,所有的设备都通过总线相互连接,甚至当它是一个内部的虚拟总线(如,platform总线);例如,设备模型表示在总线和它们控制的设备之间的实际连接;
Linux设备模型中,一个总线由内核结构体struct bus_type描述;其结构定义如下:
struct bus_type
{
const char* name; //总线类型的名称
struct subsystem subsys; //该总线所属的子系统subsystem,代表自身---kset
struct kset drivers; //该总线所使用的驱动程序的集合
struct kset devices; //挂接在该总线上的所有设备的集合
struct klist klist_devices; //挂接在该总线上的所有设备所组成的链表
struct klist klist_drivers; //该总线所使用的驱动程序所组成的链表
struct bus_attribute* bus_attrs; //总线属性
struct device_attribute* dev_attrs; //设备属性
struct driver_attribute* drv_attrs; //驱动程序属性
//设备驱动程序匹配函数
int (*match)(struct device* dev, struct device_driver* drv);
//热插拔、即插即用、电源管理,等等事件的处理函数
int (*uevent)(struct device* dev, char** envp, int num_envp, char* buffer, int buffer_size);
int (*probe)(struct device* dev);
int (*remove)(struct device* dev);
void (*shutdown)(struct device* dev);
int (*suspend)(struct device* dev, pm_message_t state);
int (*resume)(struct device* dev);
};
//其中重点看一下私有成员结构体:
struct bus_type_private {
struct kset subsys; //bus内嵌的kset,代表其自身
struct kset *drivers_kset;
struct kset *devices_kset;
struct klist klist_devices; //包含devices链表及其操作函数
struct klist klist_drivers; //driver链表及其操作函数
struct blocking_notifier_head bus_notifier;
unsigned int drivers_autoprobe:1; //匹配成功自动初始化标志
struct bus_type *bus;
};
每个bus_type对象都对应/sys/bus目录下的一个子目录,如,PCI总线对应于/sys/bus/pci目录;在每个这样的子目录下存在两个子目录:devices和drivers,分别对应于bus_type结构中的devices和drivers成员,其中,devices子目录描述的是连接在该总线上的所有设备,drivers子目录描述的是该总线所使用的所有驱动程序;/sys/bus目录下的所有子目录都类似;
2.bus初始化和注册
bus的注册在/drivers/base/bus.c里
int __init buses_init(void)
{
bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL);
return 0;
}
bus_uevent_ops,这是一个uevent的操作集。
struct kset *kset_create_and_add(const char *name,
struct kset_uevent_ops *uevent_ops,
struct kobject *parent_kobj)
//传递进来的参数为("bus", &bus_uevent_ops, NULL)
{
struct kset *kset;
int error;
//创建一个kset容器
kset = kset_create(name, uevent_ops, parent_kobj);
//注册创建的kset容器
error = kset_register(kset);
return kset;
}
首先需要创建一个kset容器
static struct kset *kset_create(const char *name,
struct kset_uevent_ops *uevent_ops,
struct kobject *parent_kobj)
//传递进来的参数为("bus", &bus_uevent_ops, NULL)
{
struct kset *kset;
//为kset分配内存
kset = kzalloc(sizeof(*kset), GFP_KERNEL);
//设置kset中kobject的名字,这里为bus
kobject_set_name(&kset->kobj, name);
//设置uevent操作集,这里为bus_uevent_ops
kset->uevent_ops = uevent_ops;
//设置父对象,这里为NULL
kset->kobj.parent = parent_kobj;
//设置容器操作集
kset->kobj.ktype = &kset_ktype;
//设置父容器
kset->kobj.kset = NULL;
return kset;
}
//将kset添加到/sys中
int kset_register(struct kset *k)
{
int err;
//初始化
kset_init(k);
//添加该容器
err = kobject_add_internal(&k->kobj);
kobject_uevent(&k->kobj, KOBJ_ADD);
return 0;
}
kset_init进行一些固定的初始化操作,里面没有我们需要关心的内容
kobject_add_internal为重要的一个函数,他对kset里kobj的从属关系进行解析,搭建正确的架构
static int kobject_add_internal(struct kobject *kobj)
{
int error = 0;
struct kobject *parent;
//检测kobj是否为空
if (!kobj)
return -ENOENT;
//检测kobj名字是否为空
if (!kobj->name || !kobj->name[0]) {
pr_debug("kobject: (%p): attempted to be registered with empty "
"name!\n", kobj);
WARN_ON(1);
return -EINVAL;
}
//提取父对象
parent = kobject_get(kobj->parent);
/* join kset if set, use it as parent if we do not already have one */
//父容器存在则设置父对象
if (kobj->kset) {//在bus的kset中为空,所以不会进入到下面的代码
//检测是否已经设置父对象
if (!parent)
//无则使用父容器为父对象
parent = kobject_get(&kobj->kset->kobj);
//添加该kobj到父容器的链表中
kobj_kset_join(kobj);
//设置父对象
kobj->parent = parent;
}
pr_debug("kobject: '%s' (%p): %s: parent: '%s', set: '%s'\n",
kobject_name(kobj), kobj, __func__,
parent ? kobject_name(parent) : "<NULL>",
kobj->kset ? kobject_name(&kobj->kset->kobj) : "<NULL>");
//建立相应的目录
error = create_dir(kobj);
kobj->state_in_sysfs = 1;
return error;
}
至此bus的目录就建立起来了
int bus_register(struct bus_type *bus)
{
int retval;
struct bus_type_private *priv;
priv = kzalloc(sizeof(struct bus_type_private), GFP_KERNEL);//进入时bus_type->bus_type_private为NULL
if (!priv) //该函数主要是对其的设置
return -ENOMEM;
priv->bus = bus; //私有成员的bus回指该bus
bus->p = priv; //初始化bus->p,即其私有属性
BLOCKING_INIT_NOTIFIER_HEAD(&priv->bus_notifier);
retval = kobject_set_name(&priv->subsys.kobj, "%s", bus->name); //设置该bus的名字,bus是kset的封装//bus_kset即为所有bus的总起始端点 //围绕bus内嵌的kset初始化,和kset的初始化时围绕
priv->subsys.kobj.kset = bus_kset; //kobj相似,没有parent时,就会用kset的kobj,此处即是
priv->subsys.kobj.ktype = &bus_ktype; //属性操作级别统一为bus_ktype
priv->drivers_autoprobe = 1;//设置该标志,当有driver注册时,会自动匹配devices
//上的设备并用probe初始化,当有device注册时也同样找到 driver并会初始化
retval = kset_register(&priv->subsys); //注册kset,创建目录结构,以及层次关系
retval = bus_create_file(bus, &bus_attr_uevent); //当前bus目录下生成bus_attr_uevent属性文件
if (retval)
goto bus_uevent_fail;
priv->devices_kset = kset_create_and_add("devices", NULL,//初始化bus目录下的devices目录,里面级联了该bus下设备,
&priv->subsys.kobj); //仍然以kset为原型
priv->drivers_kset = kset_create_and_add("drivers", NULL, //初始化bus目录下的drivers目录,里面级联了该bus下设备的driver
&priv->subsys.kobj);
klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put);//初始化klist_devices里的操作函数成员
klist_init(&priv->klist_drivers, NULL, NULL); //klist_drivers里的操作函数置空
retval = add_probe_files(bus); //增加bus_attr_drivers_probe和bus_attr_drivers_autoprobe
retval = bus_add_attrs(bus); //增加默认的属性文件
}
3.bus属性
struct bus_attribute
{
struct attribute attr;
ssize_t (*show)(struct bus_type* bus, char* buf);
ssize_t (*store)(struct bus_type* bus, const char* buf, size_t count);
};
int bus_create_file(struct bus_type* bus, struct bus_attribute* attr):为指定总线添加属性;
void bus_remove_file(struct bus_type* bus, struct bus_attribute* attr):删除指定总线上的指定属性;
-
史上最简单的SpringCloud教程 | 第八篇: 消息总线(Spring Cloud Bus)
2017-04-12 22:15:48Spring Cloud Bus 将分布式的节点和轻量的消息代理连接起来。这可以用于广播配置文件的更改或者其他的管理工作。一个关键的思想就是,消息总线可以为微服务做监控,也可以作为应用程序之间相互通讯。本文要讲述的是...转载请标明出处:
原文首发于:https://www.fangzhipeng.com/springcloud/2017/06/08/sc08-bus.html
本文出自方志朋的博客个人博客纯净版:https://www.fangzhipeng.com/springcloud/2017/06/08/sc08-bus.html
最新Finchley版本请访问:
https://www.fangzhipeng.com/springcloud/2018/08/08/sc-f8-bus.html
或者
http://blog.csdn.net/forezp/article/details/81041062Spring Cloud Bus 将分布式的节点用轻量的消息代理连接起来。它可以用于广播配置文件的更改或者服务之间的通讯,也可以用于监控。本文要讲述的是用Spring Cloud Bus实现通知微服务架构的配置文件的更改。
一、准备工作
本文还是基于上一篇文章来实现。按照官方文档,我们只需要在配置文件中配置 spring-cloud-starter-bus-amqp ;这就是说我们需要装rabbitMq,点击rabbitmq下载。至于怎么使用 rabbitmq,搜索引擎下。
二、改造config-client
在pom文件加上起步依赖spring-cloud-starter-bus-amqp,完整的配置文件如下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.forezp</groupId> <artifactId>config-client</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>config-client</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.2.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Dalston.RC1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> </project>
在配置文件application.properties中加上RabbitMq的配置,包括RabbitMq的地址、端口,用户名、密码,代码如下:
spring.rabbitmq.host=localhost spring.rabbitmq.port=5672 # spring.rabbitmq.username= # spring.rabbitmq.password=
如果rabbitmq有用户名密码,输入即可。
依次启动eureka-server、confg-cserver,启动两个config-client,端口为:8881、8882。
访问http://localhost:8881/hi 或者http://localhost:8882/hi 浏览器显示:
foo version 3
这时我们去代码仓库将foo的值改为“foo version 4”,即改变配置文件foo的值。如果是传统的做法,需要重启服务,才能达到配置文件的更新。此时,我们只需要发送post请求:http://localhost:8881/bus/refresh,你会发现config-client会重新读取配置文件
重新读取配置文件:
这时我们再访问http://localhost:8881/hi 或者http://localhost:8882/hi 浏览器显示:
foo version 4
另外,/bus/refresh接口可以指定服务,即使用"destination"参数,比如 “/bus/refresh?destination=customers:**” 即刷新服务名为customers的所有服务,不管ip。
三、分析
此时的架构图:
当git文件更改的时候,通过pc端用post 向端口为8882的config-client发送请求/bus/refresh/;此时8882端口会发送一个消息,由消息总线向其他服务传递,从而使整个微服务集群都达到更新配置文件。
四、其他扩展(可忽视)
可以用作自定义的Message Broker,只需要spring-cloud-starter-bus-amqp, 然后再配置文件写上配置即可,同上。
Tracing Bus Events:
需要设置:spring.cloud.bus.trace.enabled=true,如果那样做的话,那么Spring Boot TraceRepository(如果存在)将显示每个服务实例发送的所有事件和所有的ack,比如:(来自官网){ "timestamp": "2015-11-26T10:24:44.411+0000", "info": { "signal": "spring.cloud.bus.ack", "type": "RefreshRemoteApplicationEvent", "id": "c4d374b7-58ea-4928-a312-31984def293b", "origin": "stores:8081", "destination": "*:**" } }, { "timestamp": "2015-11-26T10:24:41.864+0000", "info": { "signal": "spring.cloud.bus.sent", "type": "RefreshRemoteApplicationEvent", "id": "c4d374b7-58ea-4928-a312-31984def293b", "origin": "customers:9000", "destination": "*:**" } }, { "timestamp": "2015-11-26T10:24:41.862+0000", "info": { "signal": "spring.cloud.bus.ack", "type": "RefreshRemoteApplicationEvent", "id": "c4d374b7-58ea-4928-a312-31984def293b", "origin": "customers:9000", "destination": "*:**" } }
本文源码下载:
https://github.com/forezp/SpringCloudLearning/tree/master/chapter8更多阅读
五、参考资料
扫码关注公众号有惊喜(转载本站文章请注明作者和出处 方志朋的博客)
-
原 史上最简单的SpringCloud教程 | 第八篇: 消息总线(Spring Cloud Bus)(Finchley版本)
2018-07-14 10:15:06转载请标明出处: ... 本文出自方志朋的博客 转载请标明出处: Spring Cloud Bus 将分布式的节点用轻量的消息代理连接起来。它可以用于广播配置文件的更改...本文要讲述的是用Spring Cloud Bus实现通知微服务...转载请标明出处:
http://blog.csdn.net/forezp/article/details/81041062
本文出自方志朋的博客个人博客纯净版:https://www.fangzhipeng.com/springcloud/2018/08/08/sc-f8-bus.html
Spring Cloud Bus 将分布式的节点用轻量的消息代理连接起来。它可以用于广播配置文件的更改或者服务之间的通讯,也可以用于监控。本文要讲述的是用Spring Cloud Bus实现通知微服务架构的配置文件的更改。
一、准备工作
本文还是基于上一篇文章来实现。按照官方文档,我们只需要在配置文件中配置 spring-cloud-starter-bus-amqp ;这就是说我们需要装rabbitMq,点击rabbitmq下载。至于怎么使用 rabbitmq,搜索引擎下。
二、改造config-client
在pom文件加上起步依赖spring-cloud-starter-bus-amqp,完整的配置文件如下:
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
在配置文件application.properties中加上RabbitMq的配置,包括RabbitMq的地址、端口,用户名、密码。并需要加上spring.cloud.bus的三个配置,具体如下:
spring.rabbitmq.host=localhost spring.rabbitmq.port=5672 spring.rabbitmq.username=guest spring.rabbitmq.password=guest spring.cloud.bus.enabled=true spring.cloud.bus.trace.enabled=true management.endpoints.web.exposure.include=bus-refresh
ConfigClientApplication启动类代码如下:
@SpringBootApplication @EnableEurekaClient @EnableDiscoveryClient @RestController @RefreshScope public class ConfigClientApplication { /** * http://localhost:8881/actuator/bus-refresh */ public static void main(String[] args) { SpringApplication.run(ConfigClientApplication.class, args); } @Value("${foo}") String foo; @RequestMapping(value = "/hi") public String hi(){ return foo; } }
依次启动eureka-server、confg-cserver,启动两个config-client,端口为:8881、8882。
访问http://localhost:8881/hi 或者http://localhost:8882/hi 浏览器显示:
foo version 3
这时我们去代码仓库将foo的值改为“foo version 4”,即改变配置文件foo的值。如果是传统的做法,需要重启服务,才能达到配置文件的更新。此时,我们只需要发送post请求:http://localhost:8881/actuator/bus-refresh,你会发现config-client会重新读取配置文件
重新读取配置文件:
这时我们再访问http://localhost:8881/hi 或者http://localhost:8882/hi 浏览器显示:
foo version 4
另外,/actuator/bus-refresh接口可以指定服务,即使用"destination"参数,比如 “/actuator/bus-refresh?destination=customers:**” 即刷新服务名为customers的所有服务。
三、分析
此时的架构图:
当git文件更改的时候,通过pc端用post 向端口为8882的config-client发送请求/bus/refresh/;此时8882端口会发送一个消息,由消息总线向其他服务传递,从而使整个微服务集群都达到更新配置文件。
本文源码下载:
https://github.com/forezp/SpringCloudLearning/tree/master/sc-f-chapter8
五、参考资料
http://blog.csdn.net/forezp/article/details/70148235
http://cloud.spring.io/spring-cloud-static/Finchley.RELEASE/single/spring-cloud.html
扫码关注有惊喜(转载本站文章请注明作者和出处 方志朋的博客)
-
Taking Bus
2017-11-08 10:14:14Bestland has a very long road and there are n bus station along the road, which are numbered 1 to n from left to right. There are m persons wanting to take the bus to some other station. You task is ... -
Bus Terminals
2017-08-10 13:55:56Yong-In city plans to build a bus network with N bus stops. Each bus stop is at a street corner. Yong-In is a modern city, so its map is a grid of square blocks of equal size. Two of these bus stops ... -
Bus Pass
2017-08-17 00:38:51You travel a lot by bus and the costs of all the seperate tickets are starting to add up. Therefore you want to see if it might be advantageous for you to buy a bus pass. The way the bus system ... -
Bus Fair
2017-11-02 12:52:38Once moving in Foolish Land you found that there is a strange Bus fair system. The fair of moving one kilometer by bus in that country is one coin. If you want to go to X km and your friend wants to ... -
Bus Schedules
2016-11-12 12:29:58He is able to enter any bus which stops at his start location at the given starting time or later, and he can also switch from a bus to another instantaneously if they happen to stop at the same ... -
CXF BUS
2017-02-23 09:11:40CXF中的BUS就是一个骨架,管理着CXF的扩展插件以及提供拦截器。注意,BUS提供的拦截器与具体的服务endpoint提供的拦截器是有一点区别的。BUS提供的拦截器将作用于所有的收到、发送以及错误(Fault)的消息。默认情况下...CXF中的BUS就是一个骨架,管理着CXF的扩展插件以及提供拦截器。注意,BUS提供的拦截器与具体的服务endpoint提供的拦截器是有一点区别的。BUS提供的拦截器将作用于所有的收到、发送以及错误(Fault)的消息。默认情况下,BUS没有为我们提供任何拦截器。一,BUS提供全局拦截器功能
下面来举例子说明,如何为所有的endpoint提供日志拦截:
<bean id=”logOutbound” class=”org.apache.cxf.interceptor.LoggingOutInterceptor”/>
<cxf:bus>
<cxf:outInterceptors>
<ref bean=”logOutbound”/>
</cxf:outInterceptors>
</cxf:bus>上面提供了拦截所有出去的消息日志。可以提供的拦截点包括:
Name Value inInterceptors 拦截接收到的消息 inFaultInterceptors 拦截接收错误消息 outInterceptors 拦截发出去的消息 outFaultInterceptors l拦截发出去的错误消息 这个拦截器与各endpoint的拦截器一样,需要实现Interceptor接口。这些拦截器都是作用于全局的。
二、CXF bus提供了一些feature。通过配置即可激活这些功能。
举例来说,bus有一个logging的feature。能够拦截所有的进入、发出以及错误的消息。呵呵,不需要配置拦截器咯,激活这个功能即可。实现这个功能的是org.apache.cxf.feature.LoggingFeature类。下面举例说明如何激活这个feature:
<cxf:bus>
<cxf:features>
<cxf:logging/>
</cxf:features>
</cxf:bus>比较简单,这样就可以输出日志了。它还提供了其他的一些feature,可以参考:
http://cxf.apache.org/docs/featureslist.html。用到的话可以查询下了。具体用法参考上面的例子即可。大概提供的feature涵盖了故障转移、加解密消息、压缩解压消息,ws-address支持,ws-policy支持以及轻量级消息转发。
当然,你也可以扩展自己的featrue,只需要继承AbstractFeature并实现initializeProvider 这个方法即可。这个方法提供了修改InterceptorProvider 的机会。查看InterceptorProvider 接口即知道,这个接口提供了访问上面提到的四个拦截的入口。
public interface InterceptorProvider {
List<Interceptor> getInInterceptors();
List<Interceptor> getOutInterceptors();
List<Interceptor> getInFaultInterceptors();
List<Interceptor> getOutFaultInterceptors();
}三、CXF bus还管理了扩展插件(extension)
比如 DestinationFactoryManager 可以在运行时从extension中获取,
Bus bus = BusFactory.getThreadDefaultBus();
DestinationFactoryManagerImpl dfm = bus.getExtension(DestinationFactoryManagerImpl.class);类似的还有BindingFactoryManager.ConduitInitiatorManager等。这些是专用位置哦。一般,这些可用对象可以从classpath以下路径看到:
META-INF/cxf/cxf.xml (e.g., in cxf-rt-core only)
META-INF/cxf/cxf-extension.xml (e.g. in cxf-rt-bindings-soap)
META-INF/cxf/cxf-property-editors.xml (e.g. in cxf-rt-transports-http)例如:可以从cxf-rt-core-****.jar包中的META-INF/cxf/cxf-extension.xml 文件中,看到以下已经注入的对象org.apache.cxf.wsdl11.WSDLManagerImpl,org.apache.cxf.phase.PhaseManagerImpl等等。
当然,你可以自定义extension。并且在自己的jar包的META-INF/cxf/cxf-extension.xml这个路径中,配置你自己的bean。这个bean是一个POJO的bean,不需要实现任何依赖于cxf的接口。当然,你也可以扩展cxf已有的功能。配置完成后,你可以在运行时bus.getExtension(your.class);来获取你的扩展啦。
我觉得这个设计虽然灵活,但设计的过于灵活啦,只是简单的把这些可用的bean放入一个map里面,以供查询使用。违背了面向对象的设计原则。我相信很多读者到这都会感觉,这个扩展可以扩展的东西其实是无限的,但刚开始却会让你无从下手。
这里有几个和Bus创建相关的类
BusFactory
定义了创建Bus的基本方法,它是一个抽象类。这里需要注意的{get|set}DefaultBus这两个方法。了解JAXWS API的朋友可能会有这样的疑问,就是JAXWS API中没有Bus这一概念,如果CXF要实现JAXWS API
接口怎么引入Bus这一对象呢?CXF在实现JAXWS API过程中,通过调用BusFactory.getDefaultBus()来设置内部模块使用的Bus。getDefaultBus会检测静态变量defaultBus赋值情况来决定是否要创建新的Bus。 在这我们就引出了在CXF中如果要使用JAXWS API来创建服务的话,我们可以预先配置好Bus,然后通过调用BusFactory.setDefaultBus(),来设置CXF 在实现JAWS API中使用的Bus。具体的例子大家可以参看AbstractJaxWsTest中的setUpBus()。在这里我们没有使用到HTTPTransport来进行UnitTest,而是使用一个简单LocalTransport来测试Client Server之间的通讯,其中奥妙大家可以慢慢体会。
CXFBusImpl
是Bus接口的具体实现。这里大家可以看看如何实现{get|set}Extension。
ExtensionManagerBus
是Bus接口的另一个实现。这个Bus通过读取Class Path 中的META-INF/bus-extensions.xml文件来获取扩展模块的信息。
在ExtensionManagerBus中的初始化代码中,你可以发现CXF core中所必须的Managers(Bus也算是一个Manager集中营)。其中有负责获取资源管理的ResourceManager,负责扩展模块管理的ExtensionManger,负责Bus生命周期管理的BusLifeCycleManager, 负责初始化Server端Transport的DestionationFactoryManager, 复杂初始化Client端Transport的ConduitInitiatorManager, 负责初始化Binding的BindingFactoryManager。这里是SoapBinding bus-extension.xml的例子。
CXFBusFactory
继承了BusFactory,并通过ExtensionManagerBus来负责加载CXF的扩展模块。
SpringBusFactory
通过SpringApplicationContext来加载CXF扩展模块。SpringBusFactory是缺省的BusFactory。这里需要说明的是SpringBusFactory需要配合spring来使用,如果Class Path中没有包含Spring jars,那CXF Core会使用CXFBusFactory来加载扩展模块。随着Spring的大量普及,相信大家会大量使用SpringBusFactory来创建Bus。
在SpringBusFactory中,初始化的Bus实例是CXFBusImpl。但是如果你搜索一下SpringBusFactory以及CXFBusImpl的代码,是不会发现类似与ExtensionManagerBus那样的初始化代码的。 这是为什么呢?当当当, 这是就是Spring的强大Wire功能,相关的Manager初始化代码转变成为了CXF.xml。有意思吧!
-
bus总线
2019-03-25 15:07:00有时候两个组件也需要通信(非父子关系)。当然Vue2.0提供了Vuex,但在简单的场景下,可以使用一个空的Vue实例作为中央事件总线。 eventBus.js放在assets ...import bus from '../../assets/eventBus';/... -
Spring Cloud Bus
2017-08-24 18:17:21发博词Spring生态消息中间件相关几个项目如下spring messaging,spring integration,spring cloud stream,spring cloud bus,项目是从前到后一次构建,后面的依赖前面的项目。本文重点介绍下spring cloud bus。... -
vue bus传参
2020-07-14 10:55:17新建一个js文件,命名为bus.js。bus.js文件的内容为: import Vue from 'vue' const bus = new Vue() export default bus 页面demo.vue包含两个组件 a.vue和b.vue a.vue执行一个事件,传递数据到b.vue 或者b.vue... -
十、消息总线Bus
2020-04-18 23:09:09SpringCloud消息总线框架Bus -
busmaster 使用教程_Busmaster使用.pdf
2020-12-24 09:42:23Busmaster使用CANoe与Busmater的CAN通讯Foton电子电器Busmaster接收、发送、记录操作准备:①安装Busmaster软件;安装硬件驱动 (581的驱动)②软件中configure选项→hardware selection→对话框中选择581硬件→确定... -
Bushound 6.1
2014-03-17 22:15:27Bushound 6.1 for x86 amd x64 (XP,win7 win8 32/64) -
Service Bus Explorer
2019-08-20 16:25:04Service Bus Exporer The Service Bus Explorer allows users to connect to a Service Bus namespace and efficiently administer messaging entities. The tool provides advanced features like import/export fu... -
bus.$emit和bus.$on的用法
2020-10-29 10:28:19bus用来传递非父子关系的数据 如两个子组件之间传递数据 子组件1 this.bus.$emit("change",param) 子组件2 this.bus.$on("change",function(param){ }) 补充:子组件中也可以写成这样的箭头函数 this.bus.$on(... -
vue bus传值
2019-04-03 14:55:44创建bus.js import Vue from 'vue' export default new Vue() 在两个组件中引入bus import Bus from '@/assets/bus.js' 组件一(test函数是绑定到页面上的一个点击事件) test () { console.log(88) Bus.$emit('... -
Bus Route
2013-12-11 11:18:08Bus Route Mr. Shim received a request to improve bus routes of a complex city and he researched the bus operation policy of this city. In the city, it operates a bus for all roads from a dep -
vue 非父子组件兄弟组件之间的通信 $bus 中央事件总线 this.$bus.$off this.$bus.$on this.$bus.$emit
2020-09-12 22:50:12然后我们就可以通过this.$bus.$emit 和this.$bus.$on 来完成非父子之间的通讯 jump(){ this.$bus.$emit('updata','参数') this.$router.push({ path:'/aaa' }) }, mounted(){ this... -
Spring Cloud Bus 无法 bus-refresh 问题
2019-03-26 18:10:37环境: Spring Cloud : Greenwich.RELEASE Spring Cloud Config:2.1.0.RELEASE ... Spring Cloud Bus:2.1.0.RELEASE Spring Boot: 2.1.3.RELEASE Spring boot Admin:2.1.3 问题描述: ... -
bus error 错误
2020-06-28 19:00:47今天调算法时,第一次发现一个“bus error”的错误,以前没有见过,现记录如下: ** 1. 什么情况下出现的?** 答:有个算法接口的参数为指针,该指针指向用户开辟的内存,如果用户开辟的内存为空,或空指针,就会报... -
javbus爬虫-老司机你值得拥有
2019-10-07 20:41:06有个朋友叫我帮忙写个爬虫,爬取javbus5上面所有的详情页链接,也就是所有的https://www.javbus5.com/SRS-055这种链接, 我一看,嘿呀,这是司机的活儿啊,我绝对不能辱没我老司机的名声(被败坏了可不好),于是... -
选择system bus还是session bus?
2014-11-18 11:23:09不同的系统在使用daemon dbus时,有两个选择,可以选择system bus, 简单些;也可以使用session bus; 手机不象PC那样有多用户,手机一般就单用户, 所以手机系统就一个session, 所以,用system bus和session ... -
LocalBUS总线
2020-03-08 11:35:014004CPU使用4根地址数据复用总线,并包含片选信号,是LocalBUS总线的雏形。
-
不使用flash播放器,使用jquery播放flv视频.zip
-
pyechart数据可视化
-
之前一些好用的架包Android架包自动初始化id,以及GsonFormat等等
-
前端架构师-速成
-
品位现代家居生活网页模板
-
SubstancePainter插件开发-基础入门
-
C++异步串口通信
-
统计学习方法读书笔记(十一)-条件随机场
-
AWS EMR 上 Spark 任务 Exit status: -100 Container released on a *lost* node 错误
-
【数据分析-随到随学】Spark理论及实战
-
测试一下
-
latex学习笔记-插入清晰的Visio与matlab图片
-
Matlab入门基础 note3——绘图与图形(1)
-
HDLBits刷题记录——FSMQ3a
-
数据类型转换、运算符、方法入门
-
校园二手物品交易系统.zip
-
SharpZipLib
-
Flex actionscript3 as3加载文件资源进度条.rar
-
java开发的 仿雷电空战游戏 源代码.zip
-
快乐家庭活动信息网页模板