You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@cxf.apache.org by "Christian Schneider (JIRA)" <ji...@apache.org> on 2013/12/09 17:10:08 UTC

[jira] [Commented] (CXF-5448) Spring integration via @Configuration & @ComponentScan annotations

    [ https://issues.apache.org/jira/browse/CXF-5448?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13843271#comment-13843271 ] 

Christian Schneider commented on CXF-5448:
------------------------------------------

I like the aproach. The annotation postprocessor cleanly publishes the beans in the spring context. So spring can do its magic in doing the injections into the user code.

The only problem I see is that we need more flexibility regarding configuration of features and other configs. The current solution to simply pick up all features is probably not good enough for general usage. At least we need some way to override the configuration for some services.

A different approach would be to define each web service bean in the @Configuration class with some nice API to do all necessary configs. It would be less convenient but more flexible.


> 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/%3c1386597934463-5737561.post@n5.nabble.com%3e 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)