4

嗨我有一個春季啓動應用程序的戰略模式。我所有的策略都有自動裝配的構造函數。我是春季引導的新手。我沒有一個最簡單的想法,我將如何爲自動裝配構造函數注入依賴關係爲戰略類編寫我的工廠。我很感激我得到的任何幫助。春季啓動內戰略

注意:我遺漏了接口和基類不混亂樣品。

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

以前所有的答案使用Spring DI的非常簡單的用法。但是也可以使用ServiceLocatorFactoryBean來創建工廠,而不必在工廠中指定任何bean。 首先定義一個接口爲您的工廠:

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

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

然後在您的應用程序:

@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(); 
    } 
} 

現在你可以定義豆(使用註解@Service,@Component或@Bean)實現/延伸它們會自動註冊到MyFactory豆,可與創建:

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 
     } 
    } 
} 

使用相同的方法與自動裝配所有的策略

3

我會建議你做你的StrategyFactory一個bean並注入到它Map<String, Strategy>。 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