I need to create an Object which is in-complete without the constructor argument. Something like this
Class A  {
  private final int timeOut
  public A(int timeout)
  {
     this.timeOut = timeout;
   }
 //...
}
I would like this Bean to be spring managed, so that I can use Spring AOP later.
<bean id="myBean" class="A" singleton="false">
</bean>
However my bean needs timeout to be passed as a dynamic value - is there a way to create a spring managed bean with dynamic value being injedcted in the constructor?
BeanFactory has a getBean(String name, Object... args) method which, according to the javadoc, allows you to specify constructor arguments which are used to override the bean definition's own arguments. So you could put a default value in the beans file, and then specify the "real" runtime values when required, e.g.
<bean id="myBean" class="A" scope="prototype">
   <constructor-arg value="0"/> <!-- dummy value -->
</bean>
and then:
getBean("myBean", myTimeoutValue);
I haven't tried this myself, but it should work.
P.S. scope="prototype" is now preferable to singleton="false", which is deprecated syntax - it's more explicit, but does the same thing.
Two options spring (no pun intended) to mind:
1. create a timeout factory, and use that as the constructor parameter. You can create a bean which implements FactoryBean, and it's job is to create other beans. So if you had something that generates salt's for encryption, you could have it return from getObject() a EncryptionSalt object. In your case you're wanting to generate Integers.
Here is an example: http://www.java2s.com/Code/Java/Spring/SpringFactoryBeanDemo.htm
2. create a timeout bean that wraps an int that's dynamically set, and leave that in the "prototype" state so it's created each time Instead of going to the hassle of creating a factory, the EncryptionSalt object could just be declared as a prototype bean, so when it's injected a new object is created each time. Place the logic into the constructor or somewhere else.
It somewhat depends what value you want the timeout to actually be.
Do it explicitly:
interface Bean {
    void setTimeout(int timeout);
}
class BeanImpl implements Bean {
    private int timeout;
    @Override
    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }
    ...
}
<bean id="bean" class="BeanImpl" scope="prototype">
    ...
    <!-- Nothing about timeout here -->
    ...
</bean>
class Client {
    private Bean bean;
    public void setBean(Bean bean) {
        this.bean = bean;
    }
    ...
    public void methodThatUsesBean() {
        int timeout = calculateTimeout();
        bean.setTimeout(timeout);
        ...
    }
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With