1 つ以上の引数を取るコンストラクタを持つクラスがあるとします。また、引数がユーザーからの何らかの入力であることが期待されているとしましょう。つまり、引数はコンパイル時または構成時に知ることができず、実行時にのみ知ることができます。クラスをプロトタイプ Spring Bean として定義する必要がありますか、それとも単に "new" で作成する必要がありますか。
それを Bean として定義する必要がある場合、どのように引数を渡すことができますか?
1 つ以上の引数を取るコンストラクタを持つクラスがあるとします。また、引数がユーザーからの何らかの入力であることが期待されているとしましょう。つまり、引数はコンパイル時または構成時に知ることができず、実行時にのみ知ることができます。クラスをプロトタイプ Spring Bean として定義する必要がありますか、それとも単に "new" で作成する必要がありますか。
それを Bean として定義する必要がある場合、どのように引数を渡すことができますか?
これは春に問題があります。クラスが他の Bean に依存していない場合は、new
. 他のSpring Beanに依存するクラスがあり、それでもいくつかのランタイム引数を渡したい場合、現在Springはそれをサポートしていません.
ただし、SPR-7431と、カスタム引数を に渡すことに関する私の記事を<lookup-methods/>
ご覧ください。すべてがうまくいけば、この機能は Spring 3.2 の一部となり、要件を満たすはずです。prototype
基本的に、コンストラクター引数を渡しながらスコープ付き Bean を作成できます。
クラスがコンテキスト内の他の Bean にも依存していない限り、それを Bean にするべきではありません。意味がありません。を使用するだけnew
です。
それを Bean にする唯一の説得力のある理由は、それが他の Bean に依存している場合です。その場合、プロトタイプ スコープの Bean が正当化されます。ただし、クラスがコンストラクターでこれらのランタイム値を必要とする場合、コンストラクターを使用する代わりに何らかのメソッドを介してそれらを注入するようにクラスを変更しない限り、実際にはそれを行うことはできません。
ルックアップメソッドを使用してコンストラクターに引数を渡すスプリング機能は、Spring 3.2.11 では機能しませんが、Spring バージョン 4.1.1 では機能します。
これを確認するために使用したコードは次のとおりです。
これはインターフェースファクトリーです...
package prueba;
public interface Factory {
Person createPersonWithDependencies(String name);
}
これは、Spring で管理したい Bean であり、helloWorldService を注入します...
package prueba;
public class Person {
private HelloWorldService helloWorldService;
public final void setHelloWorldService(HelloWorldService extraService) {
this.helloWorldService = extraService;
}
public Person() {
super();
}
public Person(String name) {
super();
this.name = name;
}
private String name;
public final String sayHello() {
return helloWorldService.getGreeting()+" I am "+name;
}
}
これは有名な helloworld サービスです。
package prueba;
public class HelloWorldService {
public String getGreeting(){
return "hello world";
}
}
これは Factory を使用したサービスの例です
package prueba;
public class Service {
private Factory factory;
public final void setFactory(Factory factory) {
this.factory = factory;
}
public void doSomeThing(){
Person bean1= factory.createPersonWithDependencies("Jhon");
System.out.println(bean1.sayHello());
Person bean2= factory.createPersonWithDependencies("Maria");
System.out.println(bean2.sayHello());
System.out.println(bean1.sayHello());
}
}
これはすべてをテストするメインクラスです
package prueba;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestLookupMethodWithArguments {
/**
* Main method.
*/
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/applicationContext.xml");
Service service=applicationContext.getBean("service",Service.class);
service.doSomeThing();
}
}
そして最後に春の設定ファイル:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="helloWorldService" class="prueba.HelloWorldService" />
<bean id="Person" class="prueba.Person" scope="prototype">
<property name="helloWorldService" ref="helloWorldService" />
</bean>
<bean id="myFactory" class="prueba.Factory">
<lookup-method name="createPersonWithDependencies" bean="Person" />
</bean>
<bean id="service" class="prueba.Service">
<property name="factory" ref="myFactory" />
</bean>
</beans>
spring 4.1.1 を使用した出力
hello world I am Jhon
hello world I am Maria
hello world I am Jhon