Reputation: 13986
I have the following controller defined:
@Controller
@RequestMapping("/test")
public class MyController extends AbstractController
{
@Autowired
public MyController(@Qualifier("anotherController") AnotherController anotherController))
{
...
}
}
I'm wondering if it's possible to use variables in the @Qualifier annotation, so that I can inject different controllers for different .properties files, e.g.:
@Controller
@RequestMapping("/test")
public class MyController extends AbstractController
{
@Autowired
public MyController(@Qualifier("${awesomeController}") AnotherController anotherController))
{
...
}
}
Whenever I try I get:
org.springframework.beans.factory.NoSuchBeanDefinitionException:
No matching bean of type [com.example.MyController] found for dependency:
expected at least 1 bean which qualifies as autowire candidate for this
dependency. Dependency annotations:
{@org.springframework.beans.factory.annotation.Qualifier(value=${awesomeController})
I've included the following bean in my config.xml file:
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:config/application.properties</value>
</list>
</property>
</bean>
But the bean doesn't work unless I declare the bean explicitly in the xml file.
How do I do this with annotations??
Upvotes: 3
Views: 2027
Reputation: 20395
I'm not sure if what you're doing is possible but I can suggest a slightly different approach, but only if you're using Spring 3.1+. You could try using Spring Profiles.
Define the different controllers you want, one per profile:
<beans>
<!-- Common bean definitions etc... -->
<beans profile="a">
<bean id="anotherController" class="...AnotherController" />
</beans>
<beans profile="b">
<!-- Some other class/config here... -->
<bean id="anotherController" class="...AnotherController"/>
</beans>
</beans>
Your Controller would lose the @Qualifier
and become something like:
@Autowired
public MyController(AnotherController anotherController) {
...
}
Then at runtime you can specify which controller bean you want to use by activating the corresponding profile using a system property, e.g.:
-Dspring.profiles.active="a"
or:
-Dspring.profiles.active="b"
It may be possible to set profiles based on a property file but you can find out more about Spring Profiles from this post on the Spring blog. I hope that helps somewhat.
Upvotes: 1
Reputation: 8293
First I think it is bad practice to make the dependency injection rely on configuration properties. You are probably going a wrong direction trying to do this.
However to answer your question: accessing placeHolder properties requires the dependency injection to be finished. To make sure it is, you can put your code that accesses the property inside a @PostContruct
annotated method.
You will need to retrieve the bean manually from the applicationContext using getBean()
method.
@Value("${awesomeController}")
private String myControllerName;
@PostConstruct
public void init(){
AnotherController myController = (AnotherController) appContext.getBean(myControllerName);
}
Upvotes: 2