cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache CXF > Configuration Design
Date Fri, 14 Aug 2009 13:52:00 GMT
<html>
<head>
    <base href="http://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/1519/1/11/_/styles/combined.css?spaceKey=CXF&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background-color: white" bgcolor="white">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
     <h2><s>Configuration Design</s></h2>
     <h4>Page <b>removed</b> by             <a href="http://cwiki.apache.org/confluence/display/~dkulp">Daniel
Kulp</a>
    </h4>
     <br/>
     <div class="notificationGreySide">
         <p>The following outlines a design for CXF configuration that meets the requirements
collected on <a href="/confluence/display/CXF/Configuration+Requirements" title="Configuration
Requirements">Configuration Requirements</a>.</p>

<h2><a name="ConfigurationDesign-ReplacingtheConfigurationAPIsandInjectingDirectlyintoConfigurableObjects"></a>Replacing
the Configuration APIs and Injecting Directly into Configurable Objects</h2>

<p>At the heart of making CXF configuration more IOC style is the relocation of the
configurable properties from an external Configuration object into the configurable object
itself, along with getters/setters that replace the generic getObject(String name, Class&lt;?&gt;
type) in the former Configuration API.&nbsp; This addresses in particular the requirements
regarding non-invasiveness and easy testability.</p>

<p>Of the two ways to achieve this (annotate configurable properties in an implementation
class and derive a schema from that, or generate a POJO from a schema and have the configurable
object inherit from it) the latter is favored for the following reasons:</p>
<ul>
	<li>Setters can be generated in such a way that they notify listeners interested in
a configuration change in a way that is independent of JMX (use the CXF management interfaces
instead).</li>
	<li>No loss of information w.r.t. constraints for a configuration property (not sure
how much of this can be compensated by extensive use of mapping annotations if we were to
use a java - to schema approach - but I have the feeling this can get very messy).</li>
	<li>Setters can validate against the schema.</li>
	<li>Base class can act as bean name provider - this is necessary as neither of the
two out-of &#45;the box approaches for deriving BeanWiringInfo would suit us in all situations:
one is to use the fully qualified  class name and another is to use the value of the "value"
attribute in Springs Configurable annotation (the latter is not an option if we want to avoid
hardcoding dependencies on Spring anyway). Either way would not support injecting multiple
instances of an HTTP destination with a different set of values each.</li>
	<li>Option to use providers so that clients need only ever use the base classes getters/setters
(we could have pre and post providers depending on whether some source of information should
supersede an injected value or only be used if nothing had been injected and the property
has no default). We may not avail of that option but it has proved helpful in the past so
I'd be reluctant to give up on that).</li>
	<li>Option to initialize defaults for properties of complex types (even with the xjc
default-value plugin you can only default values for standard types) and therefore meet the
requirement of 0 configuration.</li>
	<li>Some intelligence built-in to the base class may prove useful to manage configuration
changes (keeping a history, feed back changes to a node manager, ...).</li>
</ul>


<p>Note that this is not necessary (and not possible) for beans that are used for wiring
purposes only. It applies more to objects such as concrete destinations, conduits, rm interceptors
etc.</p>

<p>Things that need to be done:</p>
<ol>
	<li>Split the old configuration metadata files into a pure schema part and an optional
xml file containing default values (for complex elements).</li>
	<li>Write xjc plugin to code generate base beans from schema. In the future, other
stuff could be generated also (such as aop.xml files for load-time weaving in aspectJ).</li>
	<li>Remove Configuration type data members of configurable objects and calls to ConfigurationBuilder.getConfiguration(CompoundName
id, String cfgNamespace).</li>
	<li>Replace configuration.get(String name, Class&lt;?&gt; type) by getters.</li>
	<li>Upgrade to Spring 2.0 (JAXB-based property editors, BeanDefinitionParser).</li>
	<li>In a first step (pre-aspectJ) complement the call to new XYZ() with a configurer.configure(XYZ)
and provide a Spring based implementation of a configurer. This would set ApplicationContext,
BeanWiringInfoResolver, cause injection to be performed and invoke init methods, BeanFactoryPostProcessors
etc..</li>
	<li>In a next step, use load-time weaving to get rid of that call to the configurer
(aspectJ will do it for you instead,  whenever a new object of one the types specified in
the aop.xml files is created).</li>
	<li>Lastly: use schema-bean relation to support "nice xml" (in Spring).</li>
</ol>


<h2><a name="ConfigurationDesign-Scenario%3ACXF%22outofbox%22"></a>Scenario:
CXF "out of box"</h2>

<p>In this scenario a user would be using CXF without trying to integrate it in any
other container. We would expect that all our requirements are met for this case as it will
be one of the two most common cases.&nbsp;</p>

<p>The proposed solution would remove the current configuration and use Spring as the
container. This would happen via a SpringBusFactory. This bus factory would be very simple.
It would load a Spring application context with user bean definitions and bean definitions
for all the celtix components. It would then find the Bus in the context and return it.</p>

<h3><a name="ConfigurationDesign-ZeroConfiguration"></a>Zero Configuration</h3>
<p>The SpringBusFactory would load all the /META-INF/cxf/cxf-*.xml files off from the
classpath. This will find every module that is on the classpath and wire the beans together.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">new</span> ClassPathXmlApplicationContext( <span
class="code-keyword">new</span> <span class="code-object">String</span>[]
{ <span class="code-quote">"/META-INF/cxf/cxf.xml"</span>, <span class="code-quote">"/META-INF/cxf/cxf-*.xml"</span>
});
</pre>
</div></div>

<h3><a name="ConfigurationDesign-Extensibility%2FDiscovery"></a>Extensibility/Discovery</h3>
<p>Each module would have a cxf-foo.xml file which would be discovered.</p>

<p>The default wiring would be contained in this spring files.</p>


<h3><a name="ConfigurationDesign-MinimalEfforttoAchievenonDefaultBehaviour"></a>Minimal
Effort to Achieve non-Default Behaviour</h3>
<p>User would supply a /META-INF/cxf/cxf.xml file which would override the default beans
in cxf-*.xml. The SpringBusFactory would give preference to these files when loading configurations.</p>

<p>We can also use AspectJ to control the wiring of beans which aren't created in the
container. AspectJ would collaborate with Spring to wire it together correctly.<br/>
TODO: outline AspectJ scenarios and how stuff would work.</p>

<h3><a name="ConfigurationDesign-LateInstantiation"></a>Late Instantiation</h3>
<p>This would come through the spring lazy-init="true" attribute.</p>

<h3><a name="ConfigurationDesign-Documentation"></a>Documentation</h3>
<p>JAXB would generate configuration beans from the schema. </p>

<h3><a name="ConfigurationDesign-Easilyembeddedandunittestable"></a>Easily
embedded and unit testable</h3>

<p>Beans would be injectable through constructors and setters instead of provided through
a Configuration object.</p>

<h3><a name="ConfigurationDesign-BefriendlywithContainers"></a>Be friendly
with Containers</h3>

<p>Any container that can do injection will work with this.</p>

<h3><a name="ConfigurationDesign-Benoninvasive"></a>Be non invasive</h3>

<p>All the configuration dependencies are clearly defined via the APIs and there is
no need to use configuration objects.</p>

<h2><a name="ConfigurationDesign-Scenario%3ACXFinaSpringApplication"></a>Scenario:
CXF in a Spring Application</h2>
<p>The difference between the out of the box scenario and this one is that instead of
using the SpringBusFactory the user would probably already have an applicationcontext somewhere.
In this case they could just import the necessary cxf-*.xml files:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag">&lt;import resource=<span class="code-quote">"META-INF/cxf/cxf-*.xml"</span>/&gt;</span>
</pre>
</div></div>
     </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message