Spring bean с динамическим значением конструктора
Мне нужно создать объект, который является полным без аргумента конструктора. Что-то вроде этого
Class A {
private final int timeOut
public A(int timeout)
{
this.timeOut = timeout;
}
//...
}
Я хотел бы, чтобы этот Bean был spring, поэтому я могу использовать spring AOP позже.
<bean id="myBean" class="A" singleton="false">
</bean>
Однако для моего Bean требуется время ожидания для динамического значения - существует ли способ создать Bean с динамическим значением, поврежденным в конструкторе?
Ответы
Ответ 1
BeanFactory
имеет метод getBean(String name, Object... args)
, который в соответствии с javadoc позволяет указать аргументы конструктора, которые используются для переопределения bean определение собственных аргументов. Таким образом, вы можете поместить значение по умолчанию в файл beans, а затем указать "реальные" значения времени выполнения, когда требуется, например.
<bean id="myBean" class="A" scope="prototype">
<constructor-arg value="0"/> <!-- dummy value -->
</bean>
а затем:
getBean("myBean", myTimeoutValue);
Я не пробовал это сам, но он должен работать.
P.S. scope="prototype"
теперь предпочтительнее singleton="false"
, который является устаревшим синтаксисом - он более явным, но делает то же самое.
Ответ 2
Два варианта spring (каламбур не предназначен):
1. создать тайм-аут factory и использовать его как параметр конструктора.
Вы можете создать bean, который реализует FactoryBean, и его задачей является создание другого beans. Поэтому, если у вас есть что-то, что генерирует соль для шифрования, вы можете вернуть его из getObject() объекта EncryptionSalt. В вашем случае вы хотите генерировать целые числа.
Вот пример: http://www.java2s.com/Code/Java/Spring/SpringFactoryBeanDemo.htm
2. создайте тайм-аут bean, который обертывает int, который динамически установлен, и оставьте это в состоянии "prototype", чтобы он каждый раз создавал
Вместо того, чтобы переходить к созданию factory, объект EncryptionSalt можно просто объявить прототипом bean, поэтому при его вводе каждый раз создается новый объект. Поместите логику в конструктор или где-то еще.
Это зависит от того, какое значение вы хотите, чтобы на самом деле было время ожидания.
Ответ 3
Сделайте это явно:
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);
...
}
}