SpringBoot 使用策略+工厂模式的几种实现方式
SpringBoot 使用策略+工厂模式的几种实现方式
一、 方式一:结合 @PostConstruct 实现
@PostConstruct 注解是用来在 Spring 管理的 bean 初始化后立即执行某些方法。
这里通过 @PostConstruct 注解将各种实现类初始化之后加入到策略类集合Map中去。
1. 策略类
1 @Component 2 public class FuzzyDateStyle implements ShowDateStrategy { 3 4 //... 5 6 @PostConstruct 7 public void init() { 8 ShowDateFactory.setMap(strategySign(), this); 9 } 10 11 @Override 12 public ShowDateStyleEnum strategySign() { 13 return ShowDateStyleEnum.SHOW_DATE_FUZZY; 14 } 15 16 }
2. 工厂类
1 public class ShowDateFactory { 2 3 private ShowDateFactory() {} 4 5 private static final Map<ShowDateStyleEnum, ShowDateStrategy> MAP = new HashMap<>(); 6 7 public static void setMap(ShowDateStyleEnum strategy, ShowDateStrategy showDateStrategy) { 8 MAP.putIfAbsent(strategy, showDateStrategy); 9 } 10 11 public static ShowDateStrategy getMap(ShowDateStyleEnum strategy) { 12 return MAP.get(strategy); 13 } 14 15 }
二、使用ApplicationContextAware
ApplicationContextAware的作用是获取当前应用上下文
这里实现策略模式的核心是: ApplicationContext.getBeansOfType(classType)方法,获取接口 classType 的所有子类实例
1 @Component 2 public class RoleValidatorFactory implements ApplicationContextAware { 3 private static Map<RoleCodeEnum, RoleValidator> builderMap = new HashMap<>(); 4 5 @Override 6 public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 7 for (RoleValidator roleValidator : applicationContext.getBeansOfType(RoleValidator.class).values()) { 8 builderMap.put(roleValidator.source(), roleValidator); 9 } 10 } 11 public static RoleValidator getRoleValidator(RoleCodeEnum role) { 12 return builderMap.get(role); 13 } 14 }
三、使用Spring依赖注入
用过 Spring 的肯定都知道,通过@Autowired这个注解可以帮我们自动注入我们想要的 Bean。
除了这个基本功能之外, @Autowired 还有更加强大的功能,还可以注入指定类型的数组,List/Set 集合,甚至还可以是 Map 对象。知道了这个功能,当我们需要使用 Spring 实现策略模式就非常简单。
1 @Component 2 public class ProductStrategyFactory { 3 4 /** 5 * 使用依赖注入引入 ProductService 产品实现类,以 Bean名称 作为 Map 的 Key,以 Bean 实现类作为 Value 6 */ 7 @Autowired 8 private Map<String, ProductService> strategyMap = new ConcurrentHashMap<>(2); 9 10 /** 11 * 查找对应的产品的处理策略 12 * 13 * @param productName 产品名称 14 * @return 对应的产品订购逻辑实现策略 15 */ 16 public ProductService getProductStrategy(String productName) { 17 return strategyMap.get(productName); 18 } 19 20 }
比较推荐这种方式,使用起来更加简洁方便。