Лучший способ ввести значение времени выполнения - PullRequest
3 голосов
/ 29 февраля 2012

Я новичок весны.Я обнаружил, что иногда нам нужно создать объект с использованием данных времени выполнения, но в инжекторе конструктора Spring используется фиксированное значение.Я знаю, что мог бы создать метод установки и изменить его значение, но я не думаю, что это элегантное решение.Может кто-нибудь сказать мне, как это сделать?

Ответы [ 2 ]

3 голосов
/ 01 марта 2012

Использование SpEL => через другой компонент

<bean id="bank" class="UsBank">
   <property name="moneyLeft" value="100"/> <!-- initial value -->
</bean>

<bean id="bet" class="UsDollars" scope="prototype">
   <constructor-arg value="#{ bank.moneyLeft }"/>
</bean>

Допустим, бин bank куда-то внедрен, поэтому у вас есть к нему доступ:

bank.setMoneyLeft( 100 )
Bet currentBet = appContext.getBean( "bet" )

Использование SpEL => через выражение

Если этот аргумент можно вычислить с помощью произвольного выражения:

<bean id="bet" class="UsDollars" scope="prototype">
   <constructor-arg value="#{ T(java.lang.Math).random() * 100.0 }"/>
</bean>

Использование SpEL => через Свойства системы

Если ваш вариант использования позволяет использовать системные свойства:

<bean id="bet" class="UsDollars" scope="prototype">
   <constructor-arg value="#{ systemProperties['moneyLeft'] }"/>
</bean>

чтобы получить боб:

System.setProperty( "moneyLeft", "5000" )
Bet currentBet = appContext.getBean( "bet" )

Вы можете прочитать подробнее о SpEL .

Стоит отметить, что при создании bet bean прототипа => если его внедрить в другой bean-компонент, он (другой bean-компонент) также должен быть прототипом, или существует некоторая магия AOP, которая можно использовать, но это может быть не так важно в вашем случае.

Если вышеуказанный компонент не обязательно должен быть prototype (что означает, что вам потребуется только один экземпляр этого компонента, но не во время создания контекста приложения), вы можете удалить scope="prototype" и добавьте lazy="true". Это заставит Spring пытаться создать этот bean-компонент только при первом обращении к нему.

1 голос
/ 29 февраля 2012

Как правило, для этого я предпочитаю сделать фабрику примерно такой:

@Service
public class RuntimeObjectFactoryImpl implements RuntimeObjectFactory {
    private final CustomObjectTypeA oA;
    private final CustomObjectTypeB oB;

    @Autowired
    public RuntimeObjectFactoryImpl(final CustomObjectTypeA oA, final CustomObjectTypeB oB) {
        this.oA = oA;
        this.oB = oB;
    }

    @Override
    public RuntimeObject get(CustomObjectTypeC oC) {
        return new RuntimeObject(oA, oB, oC);
    }
}

Это можно настроить и в XML (что я обычно рекомендую использовать над аннотациями для подключения бизнес-сервисов, но это более презентабельно).Ответ здесь, чтобы использовать аннотации).Итак, во время выполнения:

RuntimeObject o = runtimeObjectFactory.get(new CustomObjectTypeC(...));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...