Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Spring profiles inside a namespace

Tags:

spring

jax-rs

cxf

You don't need to know CXF to answer this question.

Suppose I have the following XML declaration which creates a JAXRS server using CXF

  <jaxrs:server id="customerService" address="/service1">
    <jaxrs:serviceBeans>
      <ref bean="serviceBean1" />
      <ref bean="serviceBean2" />
      <ref bean="serviceBean3" />
    </jaxrs:serviceBeans>
  </jaxrs:server>

Now I need to find a way to customize this JAXRS server per environment, using Spring profiles mechanism. I could do something like:

 <beans profile="dev">
    <jaxrs:server id="jaxrsServer" address="/service1">
      <jaxrs:serviceBeans>
        <ref bean="serviceBean2" />
        <ref bean="serviceBean3" />
      </jaxrs:serviceBeans>
    </jaxrs:server>
  </beans>

  <beans profile="prod">
    <jaxrs:server id="jaxrsServer" address="/service1">
      <jaxrs:serviceBeans>
        <ref bean="serviceBean1" />
        <ref bean="serviceBean2" />
      </jaxrs:serviceBeans>
    </jaxrs:server>
  </beans>

But it is not what I would like to have, because my real-world JAXRS server is a bit more complicated than in my exemple.

What I am looking for is something like that:

<jaxrs:server id="jaxrsServer" address="/service1">
  <jaxrs:serviceBeans>
    <beans profile="dev">
      <ref bean="serviceBean1" />
      <ref bean="serviceBean2" />
    </beans>
    <beans profile="dev">
      <ref bean="serviceBean2" />
      <ref bean="serviceBean3" />
    </beans>
  </jaxrs:serviceBeans>
</jaxrs:server>

But it doesn't work.


I tried to externalize my list creation:

  <bean id="serviceBeansList" class="java.util.ArrayList">
    <constructor-arg>
      <list>
        <ref bean="serviceBean1"/>
        <ref bean="serviceBean2"/>
      </list>
    </constructor-arg>
  </bean>

<jaxrs:server id="jaxrsServer" address="/service1">
  <jaxrs:serviceBeans>
      <ref bean="serviceBeansList" />
  </jaxrs:serviceBeans>
</jaxrs:server>

It still doesn't work because CXF namespace handler does not "flatten" the list, so instead of dealing with a list of 2 serviceBeans objects, it deals with a list of 1 ArrayList, which is not a type handled by CXF.

The Spring XML parsing tries to get a list. I found that in CXF namespace handling code:

if ( "serviceBeans".equals(name) ) {
            List<?> list = ctx.getDelegate().parseListElement(el, bean.getBeanDefinition());
            bean.addPropertyValue(name, list);
}

Instead of referencing a bean, isn't it possible to reference a "xml declaration fragment" with Spring or something else that could work?

like image 342
Sebastien Lorber Avatar asked Nov 12 '22 17:11

Sebastien Lorber


1 Answers

Have you tried using aliases + profiles

<jaxrs:server id="jaxrsServer" address="/service1">
  <jaxrs:serviceBeans>
    <ref bean="serviceBeanA" />
    <ref bean="serviceBeanB" />
  </jaxrs:serviceBeans>
</jaxrs:server>

<beans profile="profile1">
  <alias name="serviceBean1" alias="serviceBeanA"/>
  <alias name="serviceBean2" alias="serviceBeanB" />
</beans>
<beans profile="profile2">
  <alias name="serviceBean3" alias="serviceBeanA"/>
  <alias name="serviceBean4" alias="serviceBeanB" />
</beans>

disclaimer: this answer is a pure fantasy, but the comments are somewhat limited - I'll remove if it won't work

like image 56
Boris Treukhov Avatar answered Jan 04 '23 02:01

Boris Treukhov