Spring autowire using annotations and the type defined in the properties file?

My goal is a framework where specific types of beans can be easily modified by a properties file. I also prefer XML annotations. Ideally, I would use a combination of @Resource and SpEL as follows:

 @Resource(type="#{myProperties['enabled.subtype']}") SomeInterface foo; 

where I downloaded myProperties using PropertiesFactoryBean or <util:properties> from a file, which includes:

 enabled.type = com.mycompany.SomeClassA; // which implements SomeInterface 

This does not work because the type argument must be a literal, i.e. not allowed SpEL. What is the best practice here?

Update: See my answer below.

+7
source share
3 answers

This is an example of using Spring Java Configuration.

http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-java

Or you can also do Factory.

Usage: org.springframework.beans.factory.FactoryBean <SomeInterface>

The bean name that FactoryBean implements will be treated as "SomeInterface" even if it is not.

+1
source

I think this is not possible, the solution I am inclined to make is to use a factory that creates different objects depending on the configuration property (enabled.type in your example).

A second alternative might be to use an injection named:

 @Resource(name="beanName") 

And last, if you are using Spring 3.1+, you can try using profiles and have different bean settings in different profiles if this solves your problem.

+1
source

Spring Java and Bean Configuration Defining profiles turned out to be exactly what I was looking for (thanks @ Adam-Gent and @ Guido-Garcia). The former seems necessary for a dynamic element, and the latter contributes to best practice.

Here is a solution with Java configuration and properties:

 @Configuration public class SomeClassConfig { @Value("#{myProperties['enabled.subtype']}") public Class enabledClass; @Bean SomeInterface someBean() throws InstantiationException, IllegalAccessException { return (SomeInterface) enabledClass.newInstance(); } } 

Here's a slightly less dynamic solution with profiles.

 @Configuration @Profile("dev") public class DevelopmentConfig { @Bean SomeInterface someBean() { return new DevSubtype(); } } @Configuration @Profile("prod") public class ProductionConfig { @Bean SomeInterface someBean() { return new ProdSubtype(); } } 

With profiles, an active profile is declared using one of various methods , for example, through a system property, JVM property, web.xml, etc. For example, with the JVM property:

 -Dspring.profiles.active="dev" 
+1
source

All Articles