基于工厂实现策略模式(二)
1.定义工厂bean
注意:策略类的方法上面不能有@Async 注解,否侧 applicationContext 获取不到策略类,无法自动注入到Factory中
原因:
@Slf4j
@Component
public class MessageFactory implements InitializingBean, ApplicationContextAware {
private Map<String, MessageEvenService> strategy = new HashMap<>();
/**
* spring的上下文
*/
private ApplicationContext applicationContext;
/**
* 将StrategyService的类都按照定义好的规则(fetchKey),放入strategyServiceMap中
*/
@Override
public void afterPropertiesSet() {
//初识化把所有的策略bean放进ioc,用于使用的时候获取
/*String[] beanNamesForType = applicationContext.getBeanNamesForType(MessageEvenService.class);
ArrayList<String> beanNames = new ArrayList(Arrays.asList(beanNamesForType)) ;
beanNames.forEach(
beanName->{
Object bean = applicationContext.getBean(beanName);
strategy.put(beanName,(MessageEvenService)bean);
//策略注入的bean做key,策略实现类做value
log.info("初始化消息策略模式的键值对 key={},value={}",beanName,bean);
}
);*/
Map<String, MessageEvenService> beansOfType = applicationContext.getBeansOfType(MessageEvenService.class);
strategy.putAll(beansOfType);
strategy.forEach(
(k,v)->{
log.info("初始化消息策略模式的键值对 key={},value={}",k,v);
}
);
}
/**
* 注入applicationContext
*
* @param applicationContext ac
* @throws BeansException e
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public Map<String, MessageEvenService> getStrategy(){
return strategy;
}
}
2. 定义策略接口或者抽象类
这里用的是抽象类
@Slf4j
@Service
public abstract class MessageEvenService {
public abstract void strategyMethod();
}
3. 定义策略实现类(子类)
3.1 smsMessage
@Slf4j
@Component("smsMessage")
public class SMSMessageImpl extends MessageEvenService {
@Override
public void strategyMethod() {
log.info("SMS 策略 处理业务");
}
}
3.2 smsMessage
@Slf4j
@Component("emailMessage")
public class EmailMessageImpl extends MessageEvenService {
@Override
public void strategyMethod() {
log.info("Email 策略 处理业务");
}
}
4.测试
/**
* @author Administrator
*/
@RestController
public class FactoryDemoController {
@Autowired
private MessageFactory messageFactory;
@GetMapping("/testFactory")
public String testFactory() {
messageFactory.getStrategy().forEach(
(k,v)->{
v.strategyMethod();
}
);
return "OK";
}
}
5.演示效果
5.1 项目启动时自动注入策略类到工厂
5.2 接口访问时获取策略类
http://localhost:8888/demo/testFactory