You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@cxf.apache.org by "Przemyslaw Bielicki (JIRA)" <ji...@apache.org> on 2013/12/09 16:50:07 UTC
[jira] [Created] (CXF-5448) Spring integration via @Configuration &
@ComponentScan annotations
Przemyslaw Bielicki created CXF-5448:
----------------------------------------
Summary: Spring integration via @Configuration & @ComponentScan annotations
Key: CXF-5448
URL: https://issues.apache.org/jira/browse/CXF-5448
Project: CXF
Issue Type: Improvement
Components: Integration
Affects Versions: 2.6.11
Reporter: Przemyslaw Bielicki
Priority: Minor
Hi,
as per dev mailing list thread started by me http://mail-archives.apache.org/mod_mbox/cxf-dev/201312.mbox/browser I would like to share my solution to get rid of XML file with CXF services definition.
My case is rather simple (read: uncomplete) as I just want to automatically register in CXF @WebService and @WebServiceProvider annotated classes, so that they are exposed via CXFServlet.
The end developer just needs to annotate her services with e.g. @WebService annotation and also needs to add a following Spring configuration (application code):
{code:title=SampleAppConfig.java|borderStyle=solid}
import javax.jws.WebService;
import javax.xml.ws.WebServiceProvider;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@Import(JaxWsConfig.class)
@ComponentScan(value = { "package filters" },
includeFilters = {
@Filter(WebService.class),
@Filter(WebServiceProvider.class)
})
public class SampleAppConfig {
}
{code}
where JaxWsConfig is a reference to CXF Spring configuration (it should be a part of CXF):
{code:title=JaxWsConfig.java|borderStyle=solid}
@Configuration
@ImportResource({
"classpath:META-INF/cxf/cxf.xml",
"classpath:META-INF/cxf/cxf-servlet.xml"
})
public class JaxWsConfig {
}
{code}
The crucial part is Spring bean post processor (that should be also a part of CXF distribution):
{code:title=JaxWsBeanPostProcessor.java|borderStyle=solid}
@Named
public class JaxWsBeanPostProcessor implements BeanPostProcessor {
@Inject
ListableBeanFactory beanFactory;
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (isWebService(bean)) {
Bus bus = beanFactory.getBean(Bus.DEFAULT_BUS_ID, Bus.class);
SpringEndpointImpl endpoint = new SpringEndpointImpl(bus, bean);
// capitalization is just a nice feature - totally optional
endpoint.setAddress("/" + StringUtils.capitalize(beanName));
// adds ALL features registered / discovered by Spring
Map<String, AbstractFeature> featureMap = beanFactory.getBeansOfType(AbstractFeature.class);
endpoint.getFeatures().addAll(featureMap.values());
endpoint.publish();
}
return bean;
}
boolean isWebService(Object bean) {
Class<?> beanClass = bean.getClass();
return beanClass.getAnnotation(WebService.class) != null
|| beanClass.getAnnotation(WebServiceProvider.class) != null;
}
}
{code}
And then if you also want to configure / inject your features using CDI (Spring) you do stuff like this (application code):
{code:title=MyFeature.java|borderStyle=solid}
@Named
public class MyFeature extends AbstractFeature {
@Inject
MyInInterceptor inInterceptor;
@Inject
MyOutInterceptor outInterceptor;
@Override
protected void initializeProvider(InterceptorProvider provider, Bus bus) {
processedBus.put(bus, Boolean.TRUE);
bus.getInInterceptors().add(inInterceptor);
bus.getOutInterceptors().add(outInterceptor);
}
{code}
Does that make sense?
Please note that my implementation is simplified but works for me. You should probably add all other possible customizations in JaxWsBeanPostProcessor class.
--
This message was sent by Atlassian JIRA
(v6.1.4#6159)