Search code examples
javaspring-3spring-annotations

What is the best way to inject property values in controller?


Is this really the easiest way how to inject a property in the controller from properties file? It then needs to import the property file stuff on each controller which needs some properties. In a project like mine with about 30 controllers and 10 of them needing this country property it would look like mess i guess.. Did I understand the usage of @Value correctly?

@Controller
@RequestMapping(value = "/simple")
@ImportResource("classpath:/META-INF/properties-config.xml")
public class SimpleController {

    private @Value("#{exampleProperties['simple.country']}") String country;

}

properties-config.xml (skipped the xml and schema stuff)

<beans>
    <util:properties id="exampleProperties" location="classpath:/simple.properties" />
</beans>

Also when trying to import the properties-config.xml resource in more than one controller I get such messages. It just doesn't seem the right way how to do it, but i can't figure out a better one..

01 Apr 2011 04:52:29,859 INFO  org.springframework.beans.factory.support.DefaultListableBeanFactory []: Overriding bean definition for bean 'exampleProperties': replacing [Generic bean: class [org.springframework.beans.factory.config.PropertiesFactoryBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] with [Generic bean: class [org.springframework.beans.factory.config.PropertiesFactoryBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null]

Solution

  • I think your approach is overcomplicated for this case. The typical approach is to use <context:property-placeholder>. You declare

    <context:property-placeholder location = "classpath:/simple.properties" />
    

    in a single place, and use its properties in controllers as

    private @Value("${simple.country}") String country;
    

    Also I don't think it's a good idea to use @ImportResource this way, it violates Dependency Injection principle - these properties are parts of context in which your controllers are working, therefore controllers shouldn't know how they are loaded.