Reputation: 3312
I am attempting to use SpEL to get the name of the bean currently being instantiated to allow multiple beans of same class to be created with different properties supplied by @PropertySource
. I am hoping for something like the following:
public class SampleBean {
@Value("${#{CurrentBeanName}.val}")
private String val
}
Other bean:
public class OtherBean {
@Autowired
@Qualifier(name="BeanA")
SampleBean beanA;
@Autowired
@Qualifier(name="BeanB")
SampleBean beanB;
}
properties file:
BeanA.val=VALUE A
BeanB.val=VALUE B
If I add beanName=BeanA
to my properties file, I am able to get this to work with
@Value("${${beanName}.val}")
Any ideas on what to do for #{BeanName}
? If this is impossible then so be it, but if it works it would be much cleaner than my current solution.
EDIT:
Or any way to pass a constant from the xml bean definition to SpEL? example:
<bean id="BeanA" class="...">
<property name="prefix" value="BeanA"/>
</bean>
java:
public class SampleBean {
@Value("${#{prefix}.val}")
private String val
}
Any sort of attribute or anything would work
EDIT2:
This is trivial in old XML based config
spring.xml:
<bean id="beanA" class="SampleBean">
<property name="val" value="${BeanA.val}"/>
</bean>
<bean id="beanB" class="SampleBean">
<property name="val" value="${BeanB.val}"/>
</bean>
SampleBean.java:
public class SampleBean {
private String val;
public void setVal (String val) {
this.val = val;
}
}
However when switching to the new @Value
annotations to get rid of all the setters, it seems non-singletons with diff properties aren't supported (i.e. no way to dynamically filter @Value
arguments on bean creation)
Upvotes: 0
Views: 2396
Reputation: 174664
No; it is not possible to reference the current bean.
EDIT
To address your comment below, the Java Configuration equivalent of
<bean id="BeanA" class="com.my.Foo">
<property name="prefix" value="BeanA"/>
</bean>
is
@Bean
public Foo BeanA() {
Foo a = new Foo();
a.setPrefix("BeanA");
}
although, by convention, you'd probably name it beanA
.
Upvotes: 1
Reputation: 8127
If you have singleton bean types you could just use a static final
variable for the name and then reference that. But the bigger issue is that you will be breaking the Spring
inversion of control principals if you begin depending on Spring
bean names, which is why this sort of thing isn't done. Pretty much want to focus on creating modules and domains for your project. If you begin accessing components coming from the Spring Context directly (such as the bean name) you will find that your modules will become brittle, hard to change and very hard to reason about as they begin to depend on behaviour from seemingly unrelated modules, such as the Spring Dependency Injection Framework. Although you may have a valid use-case for doing this you just need to be very very careful.
Upvotes: 0