Results 1 to 6 of 6

Thread: What's the best way to add objects to an existing JavaConfigApplicationContext?

  1. #1
    Join Date
    Mar 2009
    Posts
    19

    Default What's the best way to add objects to an existing JavaConfigApplicationContext?

    Sorry if this is obvious- I'm new to JavaConfig:

    If I have a config class something like this:

    @Configuration
    public class Config {
    @Bean
    public Foo foo() {
    return new Foo(...);
    }
    }

    and I create and use my context like this:

    JavaConfigApplicationContext context =
    new JavaConfigApplicationContext(Config.class);

    Foo foo = context.getBean(Foo.class);

    What is the best way to _programatically_ add in a (singleton) object that the Foo constructor depends on? (Something that can't be created/defined in the Config class- it's provided to my code at the time I set up my context).

    I assume I need to do something like this in my Config code:

    @Configuration
    public class Config extends ConfigurationSupport {
    @Bean
    public Foo foo() {
    return new Foo( this.getBean(Bar.class) );
    }
    }

    and then tried doing something like:

    JavaConfigApplicationContext context =
    new JavaConfigApplicationContext(Config.class);

    context.getBeanFactory().registerSingleton("bar", bar);

    Foo foo = context.getBean(Foo.class);

    But this didn't work. Do I have to create a parent context for the javaconfig context? Is there no other way to register an object so that my Configuration class code can access it?

    Thanks,
    -Dave Fogel

  2. #2
    Join Date
    Apr 2007
    Posts
    307

    Default

    Hi Dave,

    The following will work:

    Code:
    JavaConfigApplicationContext ctx = new JavaConfigApplicationContext();
    ctx.addConfigClass(Config.class);
    ctx.registerSingleton("bar", bar);
    ctx.refresh();
    Foo foo = ctx.getBean(Foo.class);
    This follows the general contract of 'refreshable' application contexts in spring. The key is to create your JavaConfigApplicationContext with no arguments. This leaves the context open for further configuration, after which you may manually refresh.
    Chris Beams
    Spring Framework committer, VMware
    http://github.com/cbeams

  3. #3
    Join Date
    Mar 2009
    Posts
    19

    Default

    Hi Chris-

    Thanks for responding. But actually I don't think that works, at least not as-is. There isn't a "registerSingleton" method on JavaConfigApplicationContext.

    I did try this approach with using:

    ctx.getBeanFactory().registerSingleton("bar", bar);

    but that didn't work- gave me an IllegalStateException. Are you sure your code above would work with the 1.0.0.M4?

    -Dave Fogel

  4. #4
    Join Date
    Apr 2007
    Posts
    307

    Default

    Ah, sorry. I was a bit hasty there!

    This will work:

    Code:
    Foo foo = new Foo();
    
    JavaConfigApplicationContext ctx = new JavaConfigApplicationContext(Config.class) {
        @Override
        protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
            beanFactory.registerSingleton("foo", foo);
        }
    };
    
    Foo foo = ctx.getBean(Foo.class);
    Chris Beams
    Spring Framework committer, VMware
    http://github.com/cbeams

  5. #5
    Join Date
    Mar 2009
    Posts
    19

    Default

    Thanks Chris, I'll try that.

    It does seem like this would be a pretty common thing for users to have to do. Maybe there should be an easier way, or at least this sort of thing could go in the docs?

    thanks again,
    -Dave Fogel

  6. #6
    Join Date
    Apr 2007
    Posts
    307

    Default

    Feel free to add an issue to this effect. As far as an easier way, we probably won't change how the internal bean factory gets customized. This is a pretty well-established pattern in the ApplicationContext hierarchy. We could expose a constructor that accepts a BeanFactory, however. This would allow users to register singletons, bean defs, etc against a standalone BeanFactory and then provide that during construction of the context. This would avoid any unnecessary hierarchical contexts and avoid the anonymous subclassing of JCAC.
    Chris Beams
    Spring Framework committer, VMware
    http://github.com/cbeams

Posting Permissions

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