- by programming
- configure the interceptor on the bus, client or endpoint level
- configure a feature which registers interceptor(s)
- configure a policy which registers interceptors
This blog will explain how this works and an example can be downloaded here.
CXF 2.4 introduced a new feature called bus extension which are loaded during the initialization phase of a bus automatically. Thus, your interceptor registration code must get notified whenever a new client or server is created to be able to add the interceptor. CXF provides three LifecycleListners:
This example shows the usage of the Server- and ClientLifecycleListner. A lifecycle listener is registered by the corresponding lifecycle manager which can be resolved using the CXF bus as illustrated in the following code snippet:
public class DemoListener implements ClientLifeCycleListener, ServerLifeCycleListener {
public DemoListener(Bus bus) {
ServerLifeCycleManager slm = bus.getExtension(ServerLifeCycleManager.class);
slm.registerListener(this);This class implements the lifecycle listener methods and registers itself to the lifecycle manager. The interceptor could be registered as illustrated in the following code snippet:
public void startServer(Server server) {
System.out.println("--------- startServer");
server.getEndpoint().getInInterceptors().add(new DemoInterceptor());
server.getEndpoint().getOutInterceptors().add(new DemoInterceptor());
}
public void clientCreated(Client client) {
System.out.println("--------- clientCreated");
client.getOutInterceptors().add(new DemoInterceptor());
client.getInInterceptors().add(new DemoInterceptor());
}
So far so good, but there must be a way to trigger the instantiation of the class DemoListener. One option is to use Spring and make this class a spring managed component or you register this bean as a CXF bus extension.
I'll explain how to register this bean as a bus extension thus it gets instantiated when the bus is created which means that the lifecycle listeners are registered in the startup phase too.
Your Jar file must contain a file called bus-extensions.xml at the following location in the Jar:
META-INF/cxf/bus-extensions.txt
The content of this text file is very simple. You just list the classname:
org.talend.ps.examples.busextension.DemoListener::false
The last parameter is false which tells the bus whether the instantiation of the bean should be defered or not. If deferred is true, (default) the bus doesn't create the beans during startup. However, if something specifically asks for one of those beans, it will be created and loaded.
If the class provides a constructor with the Bus argument, CXF will pass the bus during initialization.
Where else is this feature used? In CXF itself.
This was a very simple example how to instantiate beans during bus startup without the requirement for Spring. A lot of the advanced and WS-* features in CXF 2.3 and earlier required that you explicitly imported resources like:
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-jms.xml" />
This was required to import the spring configuration files which contained bean definitions which usually implemented lifecycle listeners or support for policy. This is not required any more in CXF 2.4 and above. You only have to import the following resource now:
<import resource="classpath:META-INF/cxf/cxf.xml" />
With CXF 2.4, these features are not plugged into the bus using a spring mechanism but instead the bus extension mechnism as illustrated in the simple example above.
If you want to see more advanced usage of bus extension have a look to the sources of some of these CXF modules:
An interesting interceptor example can be found in the Talend Service Factory.