12

Assume I'm having a large list of values aa bb cc dd ee ff gg etc., which I need to pass as a constructor in spring

If I need to configure as string array it is easy in spring as we can just specify the values as comma separated as aa, bb, cc etc.,

If I need to configure as list I need to do like below

<bean name="myBean" class="MyClass">
    <constructor-arg>
        <list>
            <value>aa</value>
            <value>bb</value>
            <value>cc</value>
            <value>dd</value>
        </list>
    </constructor-arg>
</bean>

When the number of values increased it occupies a huge lines and it looks ugly.

Could some one please help me how we can pass large values as list in string as constructor?

Nandkumar Tekale
  • 16,024
  • 8
  • 58
  • 85
Kathir
  • 497
  • 2
  • 6
  • 14

5 Answers5

22

Are the values being passed to the list comming from a properties file? If so, you can use the something like this:

<bean name="myBean" class="MyClass">
   <constructor-arg>
      <bean class="org.springframework.util.StringUtils" factory-method="commaDelimitedListToSet">
          <constructor-arg type="java.lang.String" value="${list.value}"/>
      </bean>
    </constructor-arg>
</bean> 

with the following .properties file

list.value=aa,bb,cc,dd   

And if not, you can apparently just pass then directly :

<bean name="myBean" class="MyClass">
   <constructor-arg>
      <bean class="org.springframework.util.StringUtils" factory-method="commaDelimitedListToSet">
          <constructor-arg type="java.lang.String" value="aa,bb,cc,dd"/>
      </bean>
    </constructor-arg>
</bean> 
AxxA Osiris
  • 1,219
  • 17
  • 26
  • Nope, it is just a static values. Basically i'm trying to pass a
    list for the Dozer Mapping, currently it looks
    like propertyValues targets
    Later getting the string. I'm splitting with comma separator and
    storing it in a list. instead i want to pass the parameter as
    a list. Could you please help me?
    – Kathir Jul 20 '12 at 11:40
  • I'm not all that familiar with Dozer Mapping, but a belive you can use something like this : ``, where myId is replaced by the name you give to the StringUtils bean described above. – AxxA Osiris Jul 20 '12 at 12:28
  • 2
    Beware: the factory method returns a set, which will be converted to a list *in arbitrary order*! – augurar Nov 03 '16 at 21:02
13

Spring can automatically convert any comma separated string into a list or array for you:

public class Foo {
   public void setValueList(String[] values) { ... }
}

<bean class="Foo"
      p:valueList="a,b,c,d" />
<bean class="Foo"
      c:_0="a,b,c,d" />
<bean class="Foo">
     <constructor-arg><value>a,b,c,d</value></constructor-arg>
</bean>

In fact, even if there's only 1 value, and no commas in the string, it will still work.

There's no need for the call to org.springframework.util.StringUtils that someone mentioned in another answer.

This words for constructor args as well (c:_0 is shorthand for <constructor-arg index="0"> using the c namespace.

Matt
  • 11,523
  • 2
  • 23
  • 33
5

You could try something even simpler and use Spring expression language to convert the values to a list:

<bean name="myBean" class="MyClass">
    <constructor-arg value="#{T(java.util.Arrays).asList('${list.values}')}"/>
</bean>
ahu
  • 1,492
  • 12
  • 11
Jacek Obarymski
  • 380
  • 2
  • 10
2

If you are using latest Spring framework version(Spring 3.1+ I believe), you don't need to those string split stuff in SpringEL,

Simply add PropertySourcesPlaceholderConfigurer and DefaultConversionService in your Spring's Configuration class ( the one with annotated with Configuration ) e.g,

@Configuration
public class AppConfiguration {

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }

    @Bean public ConversionService conversionService() {
        return new DefaultConversionService();
    }
}

and in your class

@Value("${list}")
private List<String> list;

Or use @Value annotation on your constructor's parameter if that's what you want to do.

Finally in the properties file

list=A,B,C,D,E

Without DefaultConversionService, you can only take comma separated String into String array when you inject the value into your field, but DefaultConversionService does a few convenient magic for you and will add those into Collection, Array, etc. ( check the implementation if you'd like to know more about it )

With these two, it even handles all the redundant whitespaces including newline, so you don't need to add additional logics to trim them.

wonhee
  • 1,581
  • 1
  • 14
  • 24
0

You could implement a constructor that takes a comma-delimited String as its argument (and split that string yourself into the values).

If you want a solution that works for any constructor/property you could look at implementing your own PropertyEditor and configure Spring to use that.

MattR
  • 6,908
  • 2
  • 21
  • 30
  • no point in that. as shown above, spring can convert a comma separated string into an array/string automatically. – Matt Jul 20 '12 at 14:02
  • not sure which version of spring that namespaced showed up, but we're on the latest. – Matt Jul 20 '12 at 18:05