4

こんにちは私は春のブートアプリケーションで戦略パターンを持っています。すべての私の戦略は、自動生成コンストラクタを持っています。私は春のブートに新しいです。私は単純な考え方を持っていません。autowiredコンストラクタが依存関係を注入したので、どのように戦略クラスのために私の工場を書きますか?私はこれを手に入れることに感謝します。春のブートの戦略

注:サンプルを乱雑にしないように、インターフェイスと基底クラスを除外します。

public class StrategyA implement Strategy { 
private DependencyA depA; 
private DependencyB depB; 
    @Autowired 
    public StragegyA(DependencyA depA, DependencyB depB) { 
     this.depA = depA; 
     this.depB = depB; 
    } 
} 

public class StrategyB implements Strategy { 
private DependencyA depA; 
private DependencyB depB; 
    @Autowired 
    public StragegyB(DependencyA depA, DependencyB depB) { 
     this.depA = depA; 
     this.depB = depB; 
    } 
} 

public class StrategyFactory { 
    public Strategy getStrategy(String strategyName) { 
     if (name.equals("StrategyA")) { 
     <b>return StrategyA; //My problem is here 
     } else { 
     return StrategyB; // And Here 
     } 
    } 
} 

答えて

3

以前のすべての答えは、春のDIのかなりまっすぐ進むの使用を使用しています。ただし、FactoryLocatorFactoryBeanを使用すると、ファクトリにBeanを指定しなくてもファクトリを作成することができます。お使いのアプリケーションに続いて

public interface MyFactory { 
    Strategy get(String type); 
} 

// Could be an abstract class 
public interface Strategy { 
    void doStuff(); 
} 

: まず、あなたの工場のためのインタフェースを定義する今、あなたは(注釈@Service、@Componentまたは@Beanを使用して)Beanを定義することができ

@Configuration 
public class AppConfiguration { 
    @Autowired 
    private BeanFactory beanFactory; 

    public ServiceLocatorFactoryBean myFactoryLocator() { 
     final ServiceLocatorFactoryBean locator = new ServiceLocatorFactoryBean(); 
     locator.setServiceLocatorInterface(MyFactory.class); 
     locator.setBeanFactory(beanFactory); 
     return locator; 
    } 

    @Bean 
    public MyFactory myFactory() { 
     final ServiceLocatorFactoryBean locator = myFactoryLocator(); 
     locator.afterPropertiesSet(); 
     return (MyFactory) locator.getObject(); 
    } 
} 

を/実装延びるとそれらは自動的にMyFactory Beanに登録されているとして作成することができます。

myFactory.get("beanName"); 

最良の部分は、あなたが怠惰とウィットと戦略Beanを登録することができますですh異なるスコープ。

5

あなたStrategyFactory別のSpring Beanを作成し、工場内のすべての戦略を注入:

@Component 
public class StrategyFactory { 
    private final List<Strategy> strategies; 

    @Autowired 
    public StrategyFactory(List<Strategy> strategies) { 
     this.strategies = strategies; 
    } 

    public Strategy getStrategy(String strategyName) { 
     // iterate through the strategies to find the right one, and return it. 
    } 
} 

私は通常stratehyを識別するために、列挙型ではなく文字列を使用して、私は、各戦略のリターンを作りますそれが処理する列挙値、反復はもちろん

return strategies.stream().filter(strategy -> strategy.getType() == type).findAny().orElseThrow(
    () -> new IllegalStateException("No strategy found for type " + type)); 

のと同じくらい簡単ですので、あなたはまた、ルックアップO(1)を作るために、コンストラクタ内の地図に戦略を保存することができます。

2
@Component 
public class StrategyFactory { 
    private StrategyA sA; 
    private StrategyB sB; 
    @Autowired 
    public StrategyFactory (StrategyA sA, StrategyB sB) { 
     this.sA = sA; 
     this.sB = sB; 
    } 
    public Strategy getStrategy(String strategyName) { 
     if (name.equals("StrategyA")) { 
     return sA; //My problem is here 
     } else { 
     return sB; // And Here 
     } 
    } 
} 

は、私はあなたがあなたのStrategyFactory Beanを作成し、それMap<String, Strategy>に注入することを示唆しているすべての戦略

3

をオートワイヤリングと同じアプローチを使用してください。 SpringはそれをキーとしてストラテジBeanの名前で埋めます。値は戦略そのものになります。それではgetMapと電話するだけです。ここで

は一例です:

@SpringBootApplication 
public class So44761709Application { 

    public static void main(String[] args) { 
     SpringApplication.run(So44761709Application.class, args); 
    } 

    public interface Strategy { } 

    @Component 
    public static class DependencyA {} 
    @Component 
    public static class DependencyB {} 

    @Component("StrategyA") 
    public static class StrategyA implements Strategy { 
     private DependencyA depA; 
     private DependencyB depB; 
     @Autowired 
     public StrategyA(DependencyA depA, DependencyB depB) { 
      this.depA = depA; 
      this.depB = depB; 
     } 
    } 

    @Component("StrategyB") 
    public class StrategyB implements Strategy { 
     private DependencyA depA; 
     private DependencyB depB; 
     @Autowired 
     public StrategyB(DependencyA depA, DependencyB depB) { 
      this.depA = depA; 
      this.depB = depB; 
     } 
    } 

    @Component 
    public class StrategyFactory { 
     @Autowired 
     private Map<String, Strategy> strategies; 

     public Strategy getStrategy(String strategyName) { 
      return strategies.get(strategyName); 
     } 
    } 

    @Bean 
    CommandLineRunner run(StrategyFactory strategyFactory) { 
     return args -> { 
      System.out.println(strategyFactory.getStrategy("StrategyB").getClass().getSimpleName()); 
      System.out.println(strategyFactory.getStrategy("StrategyA").getClass().getSimpleName()); 
     }; 
    } 
} 

プリント:

StrategyB 
StrategyA