SpringCloud项目中使用策略模式时注入为Null
需求:物联网项目中,正在实行自动化需求,大概就是满足一些条件就触发一些响应。其中触发条件是多种多样的,响应输出也是多种多样的,自然而然我就想到了策略模式,而且也方便后续种类增加时的横向扩展。
策略模式代码如下
//触发条件执行封装
/**
* @author zhangs
* @Description 自动化触发条件执行封装
* @createDate 2019/3/22
*/
public class AutoTriggerExecContext {
private IAutoTriggerExecStrategy iAutoTriggerExecStrategy;
public AutoTriggerExecContext(IAutoTriggerExecStrategy iAutoTriggerExecStrategy) {
this.iAutoTriggerExecStrategy = iAutoTriggerExecStrategy;
}
public Integer triggerAutomatic(TriggerAutomaticMO triggerAutomatic) {
return iAutoTriggerExecStrategy.triggerAutomatic(triggerAutomatic);
}
}
//接口
/**
* @author zhangs
* @Description 自动化触发执行服务(主要用于判断条件是否被触发)
* @createDate 2019/3/12
*/
public interface IAutoTriggerExecStrategy {
/**
* 触发执行
* @param triggerAutomatic
* @return
* @author zhangs
* @createDate 2019/3/12
*/
Integer triggerAutomatic(TriggerAutomaticMO triggerAutomatic);
}
//实现1
/**
* @author zhangs
* @Description 自动化触发条件执行
* @createDate 2019/3/22
*/
@Service
@Slf4j
public class AutoTriggerDevExecStrategy implements IAutoTriggerExecStrategy {
@Autowired
private IAutomaticTriggerInfoDao iAutomaticTriggerInfoDao;
/**
* 触发执行
* 此处triggerAutomatic只使用其中触发条件集
* @param triggerAutomatic
* @return
* @author zhangs
* @createDate 2019/3/12
*/
@Override
public Integer triggerAutomatic(TriggerAutomaticMO triggerAutomatic) {
log.info("{}::自动化触发条件执行服务接口--ByDevState Start::入参::{}",
Thread.currentThread().getStackTrace()[1].getMethodName(), JSON.toJSONString(triggerAutomatic));
return null;
}
}
//实现2
/**
* @author zhangs
* @Description 自动化触发条件(ByAId)执行
* @createDate 2019/3/21
*/
@Service
@Slf4j
public class AutoTriggerIdExecStrategy implements IAutoTriggerExecStrategy {
@Autowired
private IAutomaticInfoDao iAutomaticInfoDao;
@Autowired
private IAutomaticTriggerInfoDao iAutomaticTriggerInfoDao;
@Autowired
private AutomaticBasicHandle automaticBasicHandle;
/**
* 触发执行
* @param triggerAutomatic
* @return
* @author zhangs
* @createDate 2019/3/12
*/
@Override
public Integer triggerAutomatic(TriggerAutomaticMO triggerAutomatic) {
log.info("{}::自动化触发条件执行服务接口--ByAId Start::入参::{}",
Thread.currentThread().getStackTrace()[1].getMethodName(), JSON.toJSONString(triggerAutomatic));
return null;
}
}
//使用
AutoTriggerExecContext autoTriggerExecContext = new AutoTriggerExecContext(new AutoTriggerDevExecStrategy());
autoTriggerExecContext.triggerAutomatic(triggerAutomatic);
想象是挺美好的...
自测阶段,发现策略实现中的Dao接口注入的都是Null。。。
咋回事?
然后试着在Dao处、策略实现处就是一通操作,比如加上@Component。然鹅这并没有什么卵用。。。
网上一帖子看到一句话:
必须在所有使用了dao的地方,包括调用它的servcie都要进行@Autowired注入,否则之后的注入就会失败
顺着这句话,发现上述使用处不就没使用@Autowired进行注入吗?但是这个策略模式得new啊?
接着查。。。
又想到注入还有其他方式嘛--通过给实现类起别名,通过@Qualifier注解获取不同的实现类
//实现2改造如***意@Service中的别名
/**
* @author zhangs
* @createDate 2019/3/21
*/
@Service("autoTriggerIdExecStrategy")
@Slf4j
public class AutoTriggerIdExecStrategy implements IAutoTriggerExecStrategy {
@Autowired
private IAutomaticInfoDao iAutomaticInfoDao;
@Autowired
private IAutomaticTriggerInfoDao iAutomaticTriggerInfoDao;
@Autowired
private AutomaticBasicHandle automaticBasicHandle;
/**
* 触发执行
* 此处triggerAutomatic只使用其中automaticId
* @param triggerAutomatic
* @return
* @author zhangs
* @createDate 2019/3/12
*/
@Override
public Integer triggerAutomatic(TriggerAutomaticMO triggerAutomatic) {
log.info("{}::自动化触发条件执行服务接口--ByAId Start::入参::{}",
Thread.currentThread().getStackTrace()[1].getMethodName(), JSON.toJSONString(triggerAutomatic));
return null;
}
}
//使用处如下
@Resource
@Qualifier("autoTriggerIdExecStrategy")
private IAutoTriggerExecStrategy autoTriggerIdExecStrategy;
public void testAPI(@RequestBody TriggerAutomaticMO triggerAutomatic) {
AutoTriggerExecContext autoTriggerExecContext = new AutoTriggerExecContext(autoTriggerIdExecStrategy);
autoTriggerExecContext.triggerAutomatic(triggerAutomatic);
}
测试OK!