11

I am trying to use a property placeholder as the attribute for @Qualifier, as follows:

@Autowired
@Qualifier("${beanName}")
private MyBean myBean;

However, this does not work, even though the property placeholder is available as a String value:

@Value("${beanName}")
private String beanName;

What would be a good workaround here, thanks very much.

user1052610
  • 4,440
  • 13
  • 50
  • 101
  • A good workaround depends on your overall goal. So what general problem do you want to solve? – Ralph Aug 13 '13 at 13:02
  • I am using a Spring 3 ProprtySource to pass the name of the bean in to the context when it is loaded. This is the key: the bean name must be passed into the application context as an argument. The argument is recognized by the @Value annotation, but not by Qualifier. – user1052610 Aug 13 '13 at 13:25
  • 3
    But why? It could be there are better suited alternatives to your goal. If I had to take a blind guess it sounds like Spring 3.1's bean profiles might suit what you're aiming for. – Adam B Aug 13 '13 at 15:52
  • The bean name which I need to pass in to the application context cannot be known until the time the spring context is loaded, because it is retrieved from another application. So somehow I need to pass that string in, and use it in @Qualifier - or achieve the same thing in another way. – user1052610 Aug 13 '13 at 18:15

3 Answers3

17

I encountered exactly same issue. Just use Resource

@Resource(name="${beanName}")
private MyBean myBean;
1

I can't leave a comment so this is my answer:

As Adam B said maybe you can use spring profiles to achieve the result you are aiming to (wich result are you aiming?).

Another thing you can do is:

configure a map (using the spring util namespace) in your xml context configuration like this:

 <util:map id="mapId" key-type="java.lang.String" value-type="com.xxx.interface-or-superclass">
        <beans:entry key="${property.bean.name.1}" value-ref="bean1-defined-elsewehere"/>
        <beans:entry key="${property.bean.name.2}" value-ref="bean2-defined-elsewehere"/>
        <beans:entry key="${property.bean.name.3}" value-ref="bean3-defined-elsewehere"/>
  </util:map> 

then you can load this map in a bean called eg. "com.xxx.BeanSelector"

@Value("#{mapId}")
private Map<String, com.xxx.interface-or-superclass> myMap;

and add to this bean a methos like this:

public interface-or-superclass getBean(String beanName){
    return myMap.get(beanName);
}

ok now you can have your final class similar to this:

@Autowired
private BeanSelector beanSelector;

@Value("${property.name.the.bean.you.want.to.use}")
private String beanName;

private interface-or-superclass myBean;

then you can istantiate myBean (maybe inside the method afterPropertiesSet() if you are implementing the interface InitializingBean)

in this way:

myBean = beanSelector.getBean(beanName);
// then check ifthe bean is not null or something like that

Ok it's a little messy and maybe you can act in a different way based on what you want achieve, but it's a workaround.

Emanuele Ivaldi
  • 1,332
  • 10
  • 15
0

Just a try (don't really known the problem to solve) . You can use fixed bean name as usual (autowire with placeholder is not supported) but you can load different bean implementation from different xml based on property value.
. Else think about a solution based on bean alias. My 2 cents

Luca Basso Ricci
  • 17,829
  • 2
  • 47
  • 69