2016-09-18 22 views
0

カスタムコンストラクタ引数を使用してSpringでAutowireを作成するにはどうすればよいですか?以下は私のサンプルコードです。私はフィールドをautowireできませんでした。 AbstractExecutorクラスにデフォルトのコンストラクタがないため、デフォルトコンストラクタにエラーが見つかりません。デフォルトコンストラクタを導入できません。カスタムコンストラクタ引数を使用してAutowireを作成する方法

IExecutor

public interface IExecutor { 
    Object execute(); 
} 

AbstractExecutor

public abstract class AbstractExecutor implements IExecutor { 
    private IInputPropertyBean inputObject; 
    private IOutputPropertyBean outputObject; 
    public AbstractExecutor(IInputPropertyBean inputObject, IOutputPropertyBean outputObject) { 
     this.inputObject = inputObject; 
     this.outputObject = outputObject; 
    } 
    public abstract boolean isValidInput(IInputPropertyBean inputObject) ; 
    public abstract IInputPropertyBean getInputValues(IInputPropertyBean inputObject); 
    public abstract IOutputPropertyBean process(IInputPropertyBean attribute); 
    public abstract IOutputPropertyBean getOutputValues(IInputPropertyBean inputObject, IOutputPropertyBean outputObject; 
    @Override 
    public Object execute(){ 
     if(isValidInput(inputObject)){ 
      IInputPropertyBean inputAttribute = getInputValues(inputObject); 
      IOutputPropertyBean outputAttribute = process(inputAttribute); 
      outputObject = (IOutputPropertyBean) getOutputValues(outputAttribute, outputObject); 
      return outputObject; 
     } 
    } 
} 

UserExecutor

@Repository("userExecutor") 
public class UserExecutor extends AbstractExecutor { 
    public UserExecutor(@Qualifier("userInput") IInputPropertyBean inputObject, @Qualifier("userOutput")IOutputPropertyBean outputObject) { 
     super(inputObject, outputObject); 
    } 

//override methods 
} 

IInputPropertyBean

public interface IInputPropertyBean { } 

IOutputPropertyBean

public interface IOutputPropertyBean { } 

変数UserInput

@Component("userInput") 
public class UserInput implements IInputPropertyBean { //user sepecific properties } 

UserOutput

@Component("userOutput") 
public class UserOutput implements IOutputPropertyBean { //user sepecific properties } 

UserServiceImpl

@Service 
public class UserServiceImpl implements IUserService { 

    @Autowired 
    @Qualifier("userExecutor") 
    private UserExecutor userExecutor; 


    @Override 
    public UserOutput userOperation(UserInput userInput, UserOutput userOutput) { 
     // How to @Autowire UserExecutor with userInput, userOutput comming in service parameter. 

       //IExecutor executor = new UserExecutor(userInput, userOutput); 
    //return (UserOutput) executor.execute(); 
    } 
} 
+0

私はUserExecutorにデフォルトのコンストラクタを導入し、現在のコンストラクタパラメータを自動配線フィールドに置き換えることができると信じています。 –

+0

いいえ - あなたは正しい - それは動作しません:) –

答えて

1

あなたは上の@Autowiredが欠落していますUserExecutorコンストラクタ。以下は動作します:

@Repository("userExecutor") 
public class UserExecutor extends AbstractExecutor { 
    @Autowired 
    public UserExecutor(@Qualifier("userInput") UserInput input 
    , @Qualifier("userOutput") UserOutput output) { super(input, output); } 
} 

ワーキングコードはGithubで利用できます。


また、ジェネリックを使用することもできます。

public interface IInput {} 
public interface IOutput {} 

public interface IExecutor<I extends IInput, O extends IOutput> { 
    O execute(I i); 
} 

public class AbstractExecutor<I extends IInput, O extends IOutput> 
     implements IExecutor<I, O> { 
    private final I input; 
    private final O output; 

    protected AbstractExecutor(I input, O output) { 
    this.input = input; 
    this.output = output; 
    } 

    public O execute(I i) { 
    ... 
    } 
} 

@Component 
public class UserInput implements IInput {} 
@Component 
public class UserOutput implements IOutput {} 
@Repository 
public class UserExecutor extends AbstractExecutor<UserInput, UserOutput> { 
    @Autowired 
    public UserExecutor(UserInput input, UserOutput output) { 
    super(input, output); 
    } 
} 

public interface IUserService { 
    UserOutput execute(UserInput input, UserOutput output); 
} 

@Service 
public UserService implements IUserService { 
    private final UserExecutor executor; 

    @Autowired 
    public UserService(UserExecutor executor) { 
    this.executor = executor; 
    } 

    public UserOutput execute(UserInput input) { 
    return executor.execute(input); 
    } 
} 

あなたは@QualifierObjectとタイプキャスト至る所の使用を避けることができます。

+0

こんにちはマニッシュ、 お返事ありがとうございます。 UserExecutorは、UserInputおよびUserOutputのデフォルトインスタンスを使用して作成しています(プロパティはnullです)。 しかし、私が欲しいのは、UserInputとUserOutputで私が設定したプロパティでUserExecutorのインスタンスを作成する必要があるということです。 私は、UserInputとUserOutputオブジェクトがカスタムプロパティで利用可能なコントローラレイヤを持っています。 コントローラレイヤーからUserInputとUserOutputを提供してUserExecutorを作成したいと思います。 ありがとう、 Ravi – ravi

+0

'set by me'は' runtime'で別のオブジェクトを作成することを意味します。一方、Spring管理のコンストラクタは、アプリケーションの初期化時に(通常は一度だけ)呼び出されます。したがって、実行時に、あなたがあなたの投稿に提供したコードで、 '私がオブジェクトを埋め込んでいる 'というSpring管理のBeanインスタンスを'作成'することはできません。 'UserExecutor'に' @Scope( "SCOPE_PROTOTYPE") 'を追加し、そのインスタンスを' applicationContext.getBean(UserExecutor.class、userInput、userOutput) 'として取得しなければなりません。' userInput'と 'userOutput'はあなたです供給。 – manish

関連する問題