2011-07-22 14 views
7
に工場出荷時にメソッドにパラメータを渡す

方法context.getBean(名前、ユーザー)のドキュメントは春とランタイム

言う/ファクトリメソッドに 引数

を明示的なコンストラクタの引数を指定することができますが、私が何をしても(すべて試してみて)、最も論理的な設定で、初期化中にBeanがロードされるときにこれを取得します:

org.springframework.beans.factory.UnsatisfiedDependencyException: 
Error creating bean with name 'fileValidator' defined in 
PortletContext resource 
[/WEB-INF/classes/context/customer-form-portlet.xml]: Unsatisfied 
dependency expressed through constructor argument with index 0 of type 
[com.liferay.portal.model.User]: Ambiguous factory method argument 
types - did you specify the correct bean references as factory method 
arguments? 
    org.springframework.beans.factory.UnsatisfiedDependencyException: 
Error creating bean with name 'fileValidator' defined in 
PortletContext resource 
[/WEB-INF/classes/context/customer-form-portlet.xml]: Unsatisfied 
dependency expressed through constructor argument with index 0 of type 
[com.liferay.portal.model.User]: Ambiguous factory method argument 
types - did you specify the correct bean references as factory method 
arguments? 

<bean id="fileValidator" 
     class="cz.instance.transl.validation.file.FileValidator" 
     factory-method="createInstance" /> 

private FileValidator(User user) { 
    this.user = user; 
} 

public static FileValidator createInstance(User user) { 
    return new FileValidator(user); 
} 

解説は、あなたがそれを行うことができますが、XMLのそのBeanのdefinitonかないでコンストラクタの引数を指定した場合、それが失敗したと言います。

答えて

15

javadocは言う:

引数 - 使用する引数をstaticファクトリメソッドへの明示的な引数を使用してプロトタイプを作成した場合。

だから、Bean定義あなたも、工場で豆の属性を設定する抽象ファクトリを使用することができ、すなわち

<bean id="fileValidator" 
     scope="prototype" 
     class="cz.instance.transl.validation.file.FileValidator" 
     factory-method="createInstance" /> 
+0

残念ながら、プロトタイプとしても同じ方法で失敗します。 3.1.0.M2を使う – lisak

+0

@lisak:最初に、ベータ版の使用をやめ、安定版(つまり3.0.x)に固執する – skaffman

+2

これは3.1.0.M2のバグでなければならない。その理由を見つけるために、私はそれを見つけると私は切符を上げようとします。ありがとうございます – lisak

7

ファクトリメソッドを呼び出すために、SpringはcreateInstanceに渡すためにユーザインスタンスにアクセスする必要があります。この場合、私はちょうどBeanを作成していますし、それを渡す:

<bean id="user" class="something.something.User"> 
</bean> 

<bean id="validator" class="cz.instance.transl.validation.file.FileValidator" factory-method="createInstance"> 
    <constructor-arg ref="user"/> 
</bean> 
+2

私は、実行時に引数を渡すために必要と - context.getBean(name、user) – lisak

6

、プロトタイプ・スコープのBeanにする必要があります。ここではアクションを作成するActionFactoryがあります。

<bean id="actions_factory" class="com.imagina.control.actions.impl.ActionFactoryImpl"/> 

<bean id="load_person_action" class="com.imagina.control.actions.impl.LoadPersonAction" 
    factory-bean="actions_factory" factory-method="create"> 
    <constructor-arg value="load_person_action"/>  
</bean> 

アカウントでこの点を取る必要があり、この設定を使用するには:

  1. は、メソッドが静的ではありません作成します。今のインスタンスに属し
  2. コンストラクタ-argがファクトリメソッド20枚のポスト渡って読み
10

のパラメータであり、私は、実行時にパラメータを取るためにカスタムのファクトリメソッドを取得する方法は明らかではないことがわかりました特にconstructor-argタグを使用して、下の設定や静的なファクトリメソッドとして動作するクラスとしてコンテキスト内の既存のBeanを参照する必要があるためです。

<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のインスタンスを取得して、あなたは実行時に作業している値でそれを取り込むことにより、作業ました。この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があり、ファクトリメソッド呼び出しで正しいユーザBeanを使用する必要があります。

マルチユーザシステムでこれを行うには、Beanタイプをプロトタイプに変更する必要があります。また、ファクトリを表すFileValidatorのBeanを作成する必要があります(ファクトリへの依存性注入を計画している場合は)と、新しいインスタンスを表す別のBean 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 Beanを取得したいと思いますクラスで、あなたは下のテクニックを使用することができます。

public void someMethod() { 
    ... 
    User user = context.getBean("user"); 
    user.setSomethingUsefull(...); 

    FileValidator fileValidator = 
       (FileValidator)context.getBean("fileValidatorBean", 
               user); 
    ... 
} 
+0

私は春には新しいです。私はあなたの提案されたアプローチを試みて、それは私にとって完璧に働いた。しかし、なぜ私は同じbean(つまりvalidatorFactoryとfileValidatorBean)の2つの参照が必要なのか理解できません。私は単一のBean(つまりfileValidatorBean)で試しましたが、動作しません。理由を詳述する時間を余裕を持って与えてください。お願いします。 – mrugeshthaker