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