0

私は、ログイン機能の両方だけでなく@Componentとしてannotedされている2つの具象クラスFacebookSignInImplNormalSignInImplによって実装され抽象クラスの依存性注入

@Component 
public abstract class SignIn {  

    public abstract LogInOperationToken signin(User user, HttpServletRequest request); 


} 

ための抽象クラスを持っています。次のように

さて、私はサービスクラスを持っている:

@Service 
public class SignInService { 

    @Autowired(required = true) 
    private SignIn signIn;  


    public SignInService(@Qualifier("signIn") SignIn signin) { 
    this.signIn = signin; 
    } 


    public LogInOperationToken signin(User user, HttpServletRequest request) { 
     return signIn.signin(user,request); 
    } 
} 

あなたが見ることができるように、それはコンストラクタのパラメータとして抽象クラスを取ります。

私が達成しようとしているのは、いくつかのフラグをチェックしてそれに基づいて、抽象クラスに適切な実装を割り当てます:ノーマルまたはFacebookのサインインです。 SignInは、それがSignInServiceに、コンストラクタに割り当てられているように、私はそれを@Autowireすることができますどのように抽象クラスであるので

SignIn signIn = null; 

if(flag.equals("facebook")){ 
    signIn = new FacebookSignInImpl(); 
} 
else{ 
    signIn = new NormalSignInImpl(); 
} 

SignInService signInService = new SignInService(signIn); 
signInService.signIn(user, request); 

:春の依存性注入がなければ、私のような何かをするだろう。それ以上の説明が必要な場合はコメントしてください。ありがとう。

+0

を働きます。 – manish

答えて

3

抽象クラスの@Componentを作成することはできず、アプリケーションの設計は完全ではありません。

public abstract class SignIn { 
    public abstract LogInOperationToken signin(User user, HttpServletRequest request); 
} 

@Component("fcaebookSignIn") 
public class FcaebookSignIn { 
    public LogInOperationToken signin(User user, HttpServletRequest request) { 
     // implementation code 
    } 
} 

@Component("normalSignIn") 
public class NormalSignIn { 
    public LogInOperationToken signin(User user, HttpServletRequest request) { 
     // implementation code 
    } 
} 

以下のパターンに従ってください。そして、私は強く異なるコントローラを作成したり、サインイン

@Controller 
public class SignInController { 

    @Autowired 
    @Qualifier(value="fcaebookSignIn") 
    private SignIn fcaebookSignIn; 

    @Autowired 
    @Qualifier(value="normalSignIn") 
    private SignIn normalSignIn; 

    @RequestMapping (method = RequestMethod.POST, path = '/normal/signIn') 
    public User normalSignIn(@RequestBody User user, HttpServletRequest request) { 
     normalSignIn.signIn(user, request); 
    } 

    @RequestMapping (method = RequestMethod.POST, path = '/facebook/signIn') 
    public User facebookSignIn(@RequestBody User user, HttpServletRequest request) { 
     fcaebookSignIn.signIn(user, request); 
    } 
} 

の異なるタイプのためのエンドポイントを休ませることをお勧めしますしかし、あなたは、次の単一のエンドポイントを使用する必要がある場合はすべきでください[春プロファイル](http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-definition-profiles-java)を参照してください

@Controller 
public class SignInController { 

    @Autowired 
    private ApplicationContext context; 

    private SignIn signIn; 

    @RequestMapping (method = RequestMethod.POST, path = '/signIn') 
    public User normalSignIn(@RequestBody User user, HttpServletRequest request) { 
     String flag = request.getParameter("flag"); // populate this from wherever you are getting this flag 

     if(flag.equals("facebook")) { 
      signIn = context.getBean(FcaebookSignIn.class) 
     } 
     else{ 
      signIn = context.getBean(NormalSignIn.class) 
     } 

     signIn.signIn(user, request); 
    } 
} 
+0

問題は、私がパラメータとして抽象クラスを渡そうとしている 'SignInService'クラスのコンストラクタにあるようです...どのようにマッピングを提案しますか? –

+0

私はコントローラクラスでやったように、サービスクラスで同じことをやって、コンストラクタでパラメータを渡さないでください。 – Avinash