Results 1 to 7 of 7

Thread: Passing parameters into AnnotationConfigApplicationContext

  1. #1
    Join Date
    Dec 2010
    Location
    London, England
    Posts
    11

    Question Passing parameters into AnnotationConfigApplicationContext

    Hi there,
    I currently have my factory etc declared in an annotated class which is loaded into an ApplicationContext object. i.e.

    context = new AnnotationConfigApplicationContext(MQConfig.class) ;

    However as my app is a utility type jar (it's abstracting the messaging away from any calling app), I'd like to pass the username, hostname and password into the beans before they get instantiated.

    Although this sounds obvious I cannot for the life of me see how to do this with an annotated class.

    Any help would be greatly received.

    Thanks

  2. #2
    Join Date
    Oct 2005
    Location
    Boston, MA
    Posts
    2,840

    Default

    Have you looked at the @Value annotation? It works with property placeholders, e.g.: @Value("${amqp.host}").

  3. #3
    Join Date
    Dec 2010
    Location
    London, England
    Posts
    11

    Default

    Hi. Yes I have, but that would require a property file, right?

    I actually want the values to be passed in via the class that instantiates the ApplicationContext, as it may store properties in a database or some other place etc

  4. #4
    Join Date
    Apr 2007
    Posts
    307

    Default

    @eazynow,

    What you're looking for is supported in the forthcoming Spring 3.1 M1 milestone. You could upgrade to the current Spring 3.1.0.BUILD-SNAPSHOT and give the following a try:

    1) Register a PropertySourcesPlaceholderConfigurer

    If you use the spring-context-3.1.xsd schema, this is registered by default when you use <context: property-placeholder/>. Otherwise you could register it as a regular bean definition.

    2) Do the following when instantiating your context:
    Code:
    AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
    ctx.register(MQConfig.class);
    ctx.getEnvironment().getPropertySources().addFirst(new PropertiesPropertySource(myProps);
    ctx.refresh();
    Whatever properties are present in 'myProps' will be available, through the PropertySourcesPlaceholderConfigurer above, when resolving your @Value(${...}) placeholders.

    If your properties are indeed coming from a database, you need not marshall them into a java.util.Properties object if you don't wish to. You could instead extend the new PropertySource class yourself (which is quite easy) in order to directly access properties from the database. Note that you will have to initialize that DataSource yourself, as all this is happening too early for the Spring container to deal with the DataSource as a regular Spring bean.

    It sounds like you're already instantiating the AnnotationConfigAppllicationContext yourself i.e., you're in a standalone Java application. If in fact you're dealing with a web application, you'll want to take a look at the new ApplicationContextInitializer interface, and it's support through ContextLoader / ContextLoaderListener. You can set the "contextInitializerClasses" servlet context parameter, specifying your ApplicationContextInitializer class(es), and in those classes perform this kind of customization of PropertySources against the application context's Environment, as in the code example above.

    Hope this helps, and we'd love to hear your feedback. Expect the 3.1 M1 release to drop at the end of the month / beginning of February.
    Chris Beams
    Spring Framework committer, VMware
    http://github.com/cbeams

  5. #5
    Join Date
    Dec 2010
    Location
    London, England
    Posts
    11

    Default

    Thanks for the response. I've just seen I can do what I need for now using a singleton to hold the values before instantiating the beans, and referencing the singleton in the bean. But I will also have a look into what you suggested.

    As for whether this is a standalone or web app - the idea is that it could be used with either and it's up to the apps that reference this on how they store their properties etc

    Thanks again for your help

  6. #6
    Join Date
    Dec 2008
    Posts
    1

    Default

    Hi Chris, I give a tried to this:
    Code:
    @Configuration
    @PropertySource("classpath:jdbc.properties")
    public class AppConfig {
    
    	@Value("${jdbc.driverClassName}")
    	private String driverClassName;
    
    	@Bean(destroyMethod = "close")
    	public DataSource dataSource() {
    		BasicDataSource dataSource = new BasicDataSource();
    		dataSource.setDriverClassName(driverClassName);
    .......
    Results is it cannot resolve the properties jdbc.driverClassName. I think it could work by Autowiring Environment instance and using the env.getProperty("jdbc.properties"), but I would like to understand why it doesn't work the way I first tried based on what you wrote in the preceding post?

    I am using 3.1.0.RC1

    Thanks!

  7. #7
    Join Date
    Apr 2007
    Posts
    307

    Default

    @norac,

    Indeed, injecting the Environment is the generally preferred approach here, but you are correct that @Value injection should work as well. Just make sure that you've registered a PropertySourcesPlaceholderConfigurer somewhere, for example:

    Code:
    @Bean
    public static PropertySourcesPlaceholderConfigurer ppc() {
        return new PropertySourcesPlaceholderConfigurer();
    }
    Note that the use of 'static' on such a bean method is significant. Read "A note on BeanFactoryPostProcessor-returning @Bean methods" from http://static.springsource.org/sprin...tion/Bean.html for full explanation.
    Chris Beams
    Spring Framework committer, VMware
    http://github.com/cbeams

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •