Page 1 of 2 12 LastLast
Results 1 to 10 of 16

Thread: Non-singleton beans and constructor arguments

  1. #1
    Join Date
    Oct 2004
    Posts
    151

    Default Non-singleton beans and constructor arguments

    Hi!

    I have a class in a spring webapplication that it would be nice if spring could instanciate for me since it has dependencies to other beans.

    The problem is that this class has two constructors, one with arguments and one without.

    To get a new instance using the constructor without argument I guess I should use

    Code:
    appContext.getBean("myClass")
    But... is it possible to create new instances of a this bean with the constructor with arguments?

    I havn't found any method the one bellow or similar...

    Code:
    appContext.getBean("myClass", List args)

    TIA!


    -Kaj
    Last edited by kajh; Jan 20th, 2006 at 03:39 AM.

  2. #2
    Join Date
    Nov 2004
    Location
    Hilversum - The Netherlands
    Posts
    1,054

    Default

    You could do the following:

    Code:
    <bean id="bean1" class="SomeBean"/>
    
    <bean id="bean2" class="SomeBean">
         <constructor value="bla"/>
    </bean>
    But I don`t think you are asking the right question.

    To get a new instance using the constructor without argument I guess I should use

    Code:
    appContext.getBean("myClass")
    Nope.. You can ask Spring for beans, in my previous example you could ask for bean1, or bean2. The fact they use different constructors is not important if you want to retrieve a bean.

  3. #3
    Join Date
    Oct 2004
    Posts
    151

    Default

    Quote Originally Posted by Alarmnummer
    Nope.. You can ask Spring for beans, in my previous example you could ask for bean1, or bean2. The fact they use different constructors is not important if you want to retrieve a bean.

    Thank you for answering!

    I maybe was abit unclear about one thing... the bean with two constructors is non-singleton, so I need to be able to send arguments to the constuctor from the javacode where I'm asking for the bean since I'm getting a new instance of the bean each time. This bean is f.x. for storing searchresult which differs from each search ppl do.


    -Kaj

  4. #4
    Join Date
    Feb 2005
    Location
    Boston, MA
    Posts
    1,142

    Default

    Although AbstractBeanFactory supports such an method (but uses a Object[] instead of a list), it is intended for use with static factory-method functions, and is not part of any of the actual interfaces, it is only in that one class. And not all concrete BeanFactory classes (ie ClassPathXmlApplicationContext) inherit from AbstractBeanFactory.

    Anyone know why getBean(String name, Object []args) isn't part of the Spring API? I often find myself having to create a BeanFactoryAware Object factory that takes particular parameters to create my object. And even worse, I don't get a chance to set my dynamic properties before afterPropertiesSet or the init-method get invoked.
    Bill

  5. #5
    Join Date
    Aug 2004
    Posts
    107

    Default

    Quote Originally Posted by wpoitras
    Although AbstractBeanFactory supports such an method (but uses a Object[] instead of a list), it is intended for use with static factory-method functions, and is not part of any of the actual interfaces, it is only in that one class. And not all concrete BeanFactory classes (ie ClassPathXmlApplicationContext) inherit from AbstractBeanFactory.

    Anyone know why getBean(String name, Object []args) isn't part of the Spring API? I often find myself having to create a BeanFactoryAware Object factory that takes particular parameters to create my object. And even worse, I don't get a chance to set my dynamic properties before afterPropertiesSet or the init-method get invoked.
    I'm hoping for an answer as well... This is an obvious deficiency...

    Dino

  6. #6
    Join Date
    Aug 2004
    Location
    St. Louis, MO, USA
    Posts
    24

  7. #7
    Join Date
    Aug 2004
    Location
    San Mateo, CA
    Posts
    1,265

    Default

    And even worse, I don't get a chance to set my dynamic properties before afterPropertiesSet or the init method get invoked
    I recently added a new callback to InitializationAwareBeanPostProcessor--postProcessAfterInstantiation()--that would allow you to set dynamic properties before Spring properties.

    If there was sufficient demand we could consider publicly exposing a getBean() method with arguments.
    Rod Johnson - GM, SpringSource Division, VMware
    http://www.springsource.com
    Spring From the Source

  8. #8
    Join Date
    Feb 2005
    Location
    Boston, MA
    Posts
    1,142

    Default

    I recently added a new callback to InitializationAwareBeanPostProcessor--postProcessAfterInstantiation()--that would allow you to set dynamic properties before Spring properties.
    I hadn't thought of using BeanPostProcessors to solve this problem. It certainly would work. Just have my factory implement this interface, store the parameters in a ThreadLocal, call getBean and in the callback use the threadlocal to populate the new object in postProcessAfterInstantiation.
    Bill

  9. #9
    Join Date
    Feb 2005
    Location
    Boston, MA
    Posts
    1,142

    Default

    For those looking for an example, here is a quick one I came up with that uses postProcessBeforeInitialization.

    Code:
    public interface Foo {
        public void add();
    }
    
    public class FooImpl implements Foo {
        private int size;
        private String name;
    
        public int getSize() {
            return size;
        }
    
        public void setSize(int size) {
            this.size = size;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public void add() {
            // Do stuff
        }
    }
    
    public class FooFactory implements BeanPostProcessor {
        private ObjectFactory objectFactory;
        ThreadLocal arguments;
    
        // Assumes using a ObjectFactoryCreatingFactoryBean for injecting prototype bean
        public void setObjectFactory(ObjectFactory objectFactory) {
            this.objectFactory = objectFactory;
        }
    
        public Foo getFoo(String name, int size) {
            Object[] args = { name, new Integer(size) };
            arguments.set(args);
            try {
                return (Foo) objectFactory.getObject();
            } finally {
                arguments.set(null);
            }
        }
    
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            Object[] args;
            if (bean instanceof FooImpl && (args = (Object[]) arguments.get()) != null) {
                FooImpl fooBean = (FooImpl)bean;
                fooBean.setName((String) args[0]);
                fooBean.setSize(((Integer)args[1]).intValue());
            }
            return bean;
        }
    
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            return bean;
        }
    }
    Bill

  10. #10
    Join Date
    Aug 2004
    Posts
    107

    Default

    Quote Originally Posted by Rod Johnson
    I recently added a new callback to InitializationAwareBeanPostProcessor--postProcessAfterInstantiation()--that would allow you to set dynamic properties before Spring properties.

    If there was sufficient demand we could consider publicly exposing a getBean() method with arguments.
    I would vote for it. Someone in this thread gave an example of using InitializationAwareBeanPostProcessor to get around this. This should convince you that we definitely need getBean with arguments...

    dino

Posting Permissions

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