Announcement Announcement Module
Collapse
No announcement yet.
Passing parameters into AnnotationConfigApplicationContext Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • 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
    Have you looked at the @Value annotation? It works with property placeholders, e.g.: @Value("${amqp.host}").

    Comment


    • #3
      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

      Comment


      • #4
        @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.

        Comment


        • #5
          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

          Comment


          • #6
            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!

            Comment


            • #7
              @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.

              Comment

              Working...
              X