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);
        ...
    }
}