Читая 20 постов, я обнаружил, что неясно, как заставить собственный метод фабрики принимать параметры во время выполнения, тем более что мы вынуждены использовать теги constructor-arg и ссылаться на существующий компонент в контекст, как показано ниже, и рассматриваемый класс, действующий как статический фабричный метод.
<bean id="user" class="something.something.User" />
<bean id="fileValidator"
class="cz.instance.transl.validation.file.FileValidator"
factory-method="createInstance" >
<constructor-args ref="user" />
</bean>
Я получил его, работая, извлекая экземпляр bean-компонента, используемого в конструкторе-arg, из контекста, а затем заполняя его значениями, с которыми вы работаете во время выполнения. Этот bean-компонент будет использоваться в качестве параметра при получении фабрично-сгенерированного bean-компонента.
public class X {
public void callFactoryAndGetNewInstance() {
User user = context.getBean("user");
user.setSomethingUsefull(...);
FileValidator validator = (FileValidator)context.getBean("fileValidator");
...
}
}
Обратите внимание, что это не решает проблему использования context.getBean (arg1, arg2), так как этот метод не применим в этом сценарии. Причина этого заключается в том, что все эти bean-компоненты одноэлементны, и на этом этапе конструктор не вызывается. Не проблема и не о чем беспокоиться, если вы работаете в однопользовательской системе, так как в любом случае у вас в вашем контексте только 1 пользовательский компонент!
Однако для многопользовательской системы вам необходимо убедиться, что у вас есть уникальный пользовательский бин для каждого реального пользователя и что вы используете правильный пользовательский бин в вызове фабричного метода.
Для того, чтобы сделать это в многопользовательской системе, вам необходимо изменить типы bean-компонентов на прототип И вы должны создать bean-компонент вашего FileValidator, который представляет фабрику (если вы планируете внедрение зависимостей в фабрику) и еще один компонент FileValidator, представляющий ваш новый экземпляр. Они оба будут одного класса, но вы должны дать каждому уникальное имя. Смотрите ниже:
<bean id="user" scope="prototype" class="something.something.User" />
<bean id="validatorFactory"
class="cz.instance.transl.validation.file.FileValidator">
<constructor-arg value="something" />
</bean>
<bean id="fileValidatorBean"
class="cz.instance.transl.validation.file.FileValidator"
scope="prototype"
factory-method="createInstance" >
<constructor-arg ref="user" />
</bean>
и в классе, где вы хотели бы получить этот новый компонент FileValidator с завода, вы можете использовать следующую технику:
public void someMethod() {
...
User user = context.getBean("user");
user.setSomethingUsefull(...);
FileValidator fileValidator =
(FileValidator)context.getBean("fileValidatorBean",
user);
...
}