All objects specified in the default bean configuration files are created by the underlying IOC container (Spring in this case) - either when the bus is initialised or by the time they are needed. Several things happen at that point:

  1. Spring instantiates the object by invoking the constructor of the bean class (or a factory method) specified in the bean definition.
  2. Spring injects the property values from the bean definition into the newly created object - either by passing them as arguments to the constructor (constructor injection) or by invoking the corresponding setters (setter based injection).
  3. Spring invokes any post processors that the CXF runtime has registered, e.g. the Jsr250PostProcessor which takes care of invoking all @PostConstruct annotated methods in the newly created object.

However this can only occur for objects whose use you can anticipate. But when using the JAX-WS frontend to create a web service client:

URL url = getClass().getResource("/HelloWorld.wsdl");
String ns = "";
QName serviceName = new QName(ns, "HelloWorldService");
QName portName = new QName(ns, "HelloWorldPort");
Service service = Service.create(url, serviceName);
HelloWorld proxy = service.getPort(portName, HelloWorld.class);

CXF needs to look at the wsdl to decide which binding or conduit to create for the proxy. For example, depending on the child elements of the port element in the HelloWorld.wsdl, this may be a JMS or an HTTP conduit. The creation of the actual conduit is therefore left to the CXF runtime instead of the IOC container. But we can still use the IOC container to configure this newly created object - all we need to do so is identify the object so the IOC container can look for a template bean. In the case of the HTTP conduit, the identification is via the port name, and the following bean definition:

<bean name="{}HelloWorldPort.http-conduit" abstract="true">
    <property name="client">
            <http-conf:client DecoupledEndpoint="http://localhost:9999/decoupled_endpoint"/>

will cause the HTTP conduit (which is created when the proxy is created) to use a decoupled endpoint, i.e. expect responses on a separate incoming connection.
The registration of property editors for JAXB generated types such as HTTPClientPolicy (the value type for the client property) enables the bean configuration parser to handler the syntax above (the editors are registered by the property editor registrars defined in the cxf-property-editors.xml files).

Note that the above bean is declared abstract (hence the bean class need to be specified). This underlines the fact that in this case we don't want the IOC container to create this object for us. Instead we want the IOC container to inject its properties into an object that the runtime created for us (to perform steps 2. and 3. listed above).

Aside from conduits, other objects that - depending on the use of the frontend, may be created by the runtime include destinations, services, client.server endpoints and bindings.
Please check the code for how these can be identified.

Note that the container can inject dependencies (i.e. references to other objects) as well as actual property values (e.g. for the "client" property") into such objects. So it is possible for example to include a custom handler only in the interceptor chain used for the HelloWorld endpoint:

<bean name="{}HelloWorldPort" abstract="true">
    <property name="outInterceptors">
            <ref bean="myLoggingInterceptor"/>
  • No labels