我眼中的CXF之Configuration 博客分类: ESB Spring配置管理Bean项目管理Blog
程序员文章站
2024-02-22 16:12:46
...
对于一个成熟的软件产品来说,都会涉及到配置这块的内容。对于CXF来说也不例外,如果没有Configuration模块的话是很难实现灵活的配置功能。
CXF的内部构架是支持灵活的扩展功能的, 在我前面的Blog中介绍过采用Bus来实现各模块间的解耦。而各个模块之间涉及到了很多配置的功能,例如HTTP Client端连接超时的设置,HTTP Server端是否要维护Session信息等,或者我们要发布一个服务,想采用UnWrapped编码方式,采用Aegis DataBinding,这些都是通过CXF的配置模块来实现的。简单来说CXF的配置根据配置项目的来源分为配置文件,WSDL文件,API配置。配置文件是通过XML定义的对CXF各模块配置项目定义文件, WSDL主要是通过WSDL Extension来定义了的有关Endpoint的扩展信息,而API是通过调用Java对象所提供的方法来实现对特定参数的设置功能。
在这里重点介绍CXF如何从配置文件获取配置信息以及如何实现对内部模块配置功能的。
在很多介绍CXF的文章中都说Spring是CXF中的第一公民,很多构架都是建立在Spring基础之上的。我们可以通过Spring实现灵活丰富的配置功能。概括的说CXF的Configuration配置文件部分的实现是建立在Spring Bean的基础之上的,前后发展大概经历了两个阶段,一个是Celtix建立的XML通过JAXB解析成为Spring Bean对象,一个与Xfire合并之后发展建立在Spring2.0基础上的ServerFactoryBean, ClientProxyFactoryBean系列。
CXF的配置模块是建立在Bus基础上,通过Configuration各种配置信息的管理配置功能,其核心就是我们现在看到的为个模块定义的文件。通过 JAXB 的XJC 工具,我们可以很容易的获取到schema对应的java class,通过JAXB完成schema文件到Java Object的映射。这里我们简单看一下几个核心模块的源代码。
Configurer
定义了根据Bean的实例名从Spring ApplicationContext中的配置信息的接口。
ConfigurerImpl
ConfigurerImpl继承了BeanConfigurerSupport提供了一个根据Bean name获取Spring Application Context中WiringInfo的方法,并将这些WiringInfo配置到被配置的对象中去。这里大家可以重点关注一下configureBean的方法具体实现。
正是CXF ConfigureImpl提供这一通用的配置接口,使得CXF的主要模块中的构造函数,或者是对象初始化入口中都包含这样的代码就是initconfig方法。
下面是JMSDestination中的一个initConfig的具体代码
CXF的内部构架是支持灵活的扩展功能的, 在我前面的Blog中介绍过采用Bus来实现各模块间的解耦。而各个模块之间涉及到了很多配置的功能,例如HTTP Client端连接超时的设置,HTTP Server端是否要维护Session信息等,或者我们要发布一个服务,想采用UnWrapped编码方式,采用Aegis DataBinding,这些都是通过CXF的配置模块来实现的。简单来说CXF的配置根据配置项目的来源分为配置文件,WSDL文件,API配置。配置文件是通过XML定义的对CXF各模块配置项目定义文件, WSDL主要是通过WSDL Extension来定义了的有关Endpoint的扩展信息,而API是通过调用Java对象所提供的方法来实现对特定参数的设置功能。
在这里重点介绍CXF如何从配置文件获取配置信息以及如何实现对内部模块配置功能的。
在很多介绍CXF的文章中都说Spring是CXF中的第一公民,很多构架都是建立在Spring基础之上的。我们可以通过Spring实现灵活丰富的配置功能。概括的说CXF的Configuration配置文件部分的实现是建立在Spring Bean的基础之上的,前后发展大概经历了两个阶段,一个是Celtix建立的XML通过JAXB解析成为Spring Bean对象,一个与Xfire合并之后发展建立在Spring2.0基础上的ServerFactoryBean, ClientProxyFactoryBean系列。
CXF的配置模块是建立在Bus基础上,通过Configuration各种配置信息的管理配置功能,其核心就是我们现在看到的为个模块定义的文件。通过 JAXB 的XJC 工具,我们可以很容易的获取到schema对应的java class,通过JAXB完成schema文件到Java Object的映射。这里我们简单看一下几个核心模块的源代码。
Configurer
定义了根据Bean的实例名从Spring ApplicationContext中的配置信息的接口。
ConfigurerImpl
ConfigurerImpl继承了BeanConfigurerSupport提供了一个根据Bean name获取Spring Application Context中WiringInfo的方法,并将这些WiringInfo配置到被配置的对象中去。这里大家可以重点关注一下configureBean的方法具体实现。
正是CXF ConfigureImpl提供这一通用的配置接口,使得CXF的主要模块中的构造函数,或者是对象初始化入口中都包含这样的代码就是initconfig方法。
下面是JMSDestination中的一个initConfig的具体代码
java 代码
- private void initConfig() {
- this.runtimePolicy = endpointInfo.getTraversedExtensor(new ServerBehaviorPolicyType(),ServerBehaviorPolicyType.class);
- this.serverConfig = endpointInfo.getTraversedExtensor(new ServerConfig(), ServerConfig.class);
- this.address = endpointInfo.getTraversedExtensor(new AddressType(), AddressType.class);
- this.sessionPool = endpointInfo.getTraversedExtensor(new SessionPoolType(), SessionPoolType.class);
- Configurer configurer = base.bus.getExtension(Configurer.class);
- if (null != configurer) {
- configurer.configureBean(this);
- }
- }
这里包含了两部分的内容,一个是从WSDL扩展信息中获取有个JMSDestination 服务端的运行试配置,服务器端配置和地址以及会话池部分的配置信息, 另一部分就是通过CXF Configurer模块处理相关的配置信息。 这里值得一提的是从这个函数可以看到CXF内部定义的配置顺序就是先WSDL,后配置文件,再API。越到后面配置的级别越高,可以很轻松的实现不同级别的配置重载。
CXF在后续的发展中将Xfire中的服务创建模型引入并发展开来 通过自定BeanDefinitionParaser,跳过了原有的JAXB解析模块,直接配置ServerFactoryBean或者是ClientProxyFactoryBean,这样极大简化了配置文件的定义工作量,并且提供很大扩展空间。有关CXF Spring Client,Server, Endpoint 配置文件的介绍大家可以参考我以前写的一篇blog。
在这里简单介绍一下我在实现JettyServerEngine的Spring配置过程的一点心得。JettyHttpServerEngineFactory和JettyHttpServerEngine两者之间存在父子关系,你需要在对应的JettyHttpServerEngineFactoryBeanDefinitionPaser中解析有关JettyHttpServerEngineFactory的信息,但是需要注意的是BeanDefinitionPaser中解析的获得的对象只是一个BeanDefinitionHolder,而不是具体的JettyServerEngine实例,因此你需要在BeanFactory将BeanDefinition初始化完全后,进入Wiring阶段才能将设置好的JettyServerEngine放置到JettyServerEngineFactory中。