精华内容
下载资源
问答
  • bus

    千次阅读 2013-08-21 11:15:57
    1.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):删除指定总线上的指定属性;



    展开全文
  • Spring 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/81041062

    Spring 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 教程汇总

    SpringBoot教程汇总

    Java面试题系列汇总

    五、参考资料

    spring_cloud_bus

    SouthEast
    扫码关注公众号有惊喜

    (转载本站文章请注明作者和出处 方志朋的博客

    展开全文
  • 转载请标明出处: ... 本文出自方志朋的博客 转载请标明出处: 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


    扫码关注有惊喜

    (转载本站文章请注明作者和出处 方志朋的博客

    展开全文
  • Bus Terminals

    2017-08-10 13:55:56
    Yong-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 Fair

    2017-11-02 12:52:38
    Once 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:58
    He 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:40
    CXF中的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。有意思吧!

     

    展开全文
  • javbus爬虫-老司机你值得拥有

    万次阅读 2019-10-07 20:41:06
    有个朋友叫我帮忙写个爬虫,爬取javbus5上面所有的详情页链接,也就是所有的https://www.javbus5.com/SRS-055这种链接, 我一看,嘿呀,这是司机的活儿啊,我绝对不能辱没我老司机的名声(被败坏了可不好),于是...
  • 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。...
  • busmaster 使用教程_Busmaster使用.pdf

    千次阅读 2020-12-24 09:42:23
    Busmaster使用CANoe与Busmater的CAN通讯Foton电子电器Busmaster接收、发送、记录操作准备:①安装Busmaster软件;安装硬件驱动 (581的驱动)②软件中configure选项→hardware selection→对话框中选择581硬件→确定...
  • Service Bus Explorer

    2019-08-20 16:25:04
    Service 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:19
    bus用来传递非父子关系的数据 如两个子组件之间传递数据 子组件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:08
    Bus 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
  • 十、消息总线Bus

    万次阅读 2020-04-18 23:09:09
    SpringCloud消息总线框架Bus
  • 然后我们就可以通过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. 什么情况下出现的?** 答:有个算法接口的参数为指针,该指针指向用户开辟的内存,如果用户开辟的内存为空,或空指针,就会报...
  • 选择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:01
    4004CPU使用4根地址数据复用总线,并包含片选信号,是LocalBUS总线的雏形。
  • 解决BUS ERROR

    千次阅读 2019-10-15 14:53:43
    记录在arm 板上抛出 BUS error错误 在ubuntu上运行正常,交叉编译后放入开发板的环境下运行,出现bus error的错误。 解决:找了半天原因,是我所使用的libevent框架版本没有统一,交叉编译器使用的是2.0.1而开发板上...
  • spring cloud bus

    千次阅读 2018-10-30 16:49:33
    在MQ上会创建一个 springCloudBus 的 exchange 每个服务都会创建一个 springCloudBus.anonymous.xxx 的队列(queue) --springCloudBus.anonymous.Bp0n_077SIaJXXZFzGS_hQ 每个queue都会绑定exchange,routingKey 为...
  • Vue全局Bus

    千次阅读 2019-01-25 11:09:11
    Vue组件嵌套太深,要实现组件之间的通信,又因项目太小不想用Vuex怎么办,来一起写一个Vue全局Bus吧。 众所周知,一个中央事件总线bus,我们可以用来解决兄弟组件和嵌套很多层的组件之间的通信问题,一个页面 一个...
  • 1. spring cloud bus介绍 Spring cloud bus使用轻量级消息代理将分布式系统的节点连接起来,可以使用此代理,广播状态更改(例如配置更改)或其他管理指令。它可以用作应用程序之间的通信通道。该项目提供了两种消息...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 47,827
精华内容 19,130
关键字:

bus