关于使用spring框架的时候抽象类中注入其他实现类失败的解决方法

这几天帮朋友解决问题的时候发现了一个我不知道的东西 特意叫朋友拿来了我们修改好的源代码 所以呢顺便记录一下 也跟大家分享分享。

首先我们来看抽象类的代码 

/**
 * 抽象基类,为所有子类提供一个 流程操作算法框架。 
 * @author 
 */
@Transactional
public abstract  class RefreshBeverage {
    @Resource
    private TaskFollowMapper taskFollowMapper;


    @Resource
    private TaskMapper taskMapper;


    @Resource
    private FlowLinkMapper flowLinkMapper;
    

    @Resource(name = "taskFollowIdService")
    private StepSequenceFactory taskFollowIdService;


    /**
     * 流程操作的模板方法。 分装类所有子类共同遵循的算法框架 final:是得它不能被子类所复写 原则:子类可以替换父类中可变逻辑,但不可以改变整体逻辑结构
     */


    /**
     * 流程操作模板。
     * @param staff 参数 用户实体
     * @param rwid 参数 任务ID
     * @param op 参数 操作
     * @return boolean
     */
    public final boolean prepareBeverageTemplate(Map<String, Object> params) {
        // 步骤1 任务查询
        Task task = taskSelect(params);
        // 步骤2 最新流程跟踪信息查询
        params.put("pkid", task.getRwgzid());
        TaskFollow taskFollow = taskFollowSelect(params);
        // 步骤3 流程线中获取下一个节点
        params.put("lcid", taskFollow.getLcid());
        params.put("sygjd", taskFollow.getJdid());
        FlowLink flowLink = flowLinkSelect(params);

        // 判断是否有下一个节点,如果没有,则提前结束
        if (flowLink == null) {
            return false;
        }
        // 步骤4 流程跟踪修改
        params.put("czsj", DateUtil.getCrrentTime());
        taskFollowUpdate(params);
        // 步骤5 流程跟踪插入
        String pkid = String.valueOf(taskFollowIdService.create());
        params.put("pkid", pkid);
        params.put("jdid", flowLink.getXygjd());
        taskFollowInsert(params);
        // 判断一下是否到了结束节点
        if (flowLink.getXygjd().equals(Constants.FLOW_STATUS_CLOSE)) {
            //步骤6 修改状态为完成并更新任务跟踪ID
            params.put("rwgzid", pkid);
            params.put("rwzt", Constants.EXAMINE_AND_APPROVE_FINISH);
            taskUpdate(params);
        } else {
            // 步骤6 任务信息修改
            params.put("rwgzid", pkid);
            taskUpdate(params);
        }
        if (isCustome()) {
            // 步骤7 任务状态信息修改(占时只有驳回操作才会执行)
            taskUpdateRwzt(params);
        }
        return true;
    }
 /**
     * 询问用户是否驳回: Hook,钩子函数,提供一个默认或空的实现 具体子类可以自行决定是否挂钩以及如何挂钩。
     * @return boolean
     */
    protected boolean isCustome() {
        return false;
    }


    // private对子类减少复杂度,隐藏细节
    private Task taskSelect(Map<String, Object> params) {
        Task task=taskMapper.selectTaskByrwid(params);
        return task;
    }


    // private对子类减少复杂度,隐藏细节
    private TaskFollow taskFollowSelect(Map<String, Object> params) {
        return taskFollowMapper.selectTaskFollowByrwgzid(params);
    }


    // private对子类减少复杂度,隐藏细节
    private FlowLink flowLinkSelect(Map<String, Object> params) {
        return flowLinkMapper.selectNextNote(params);
    }


    // private对子类减少复杂度,隐藏细节
    private void taskFollowUpdate(Map<String, Object> params) {
        taskFollowMapper.updateBypkid(params);
    }


    // private对子类减少复杂度,隐藏细节
    private void taskFollowInsert(Map<String, Object> params) {
        taskFollowMapper.insert(params);
    }
    
    // private对子类减少复杂度,隐藏细节
    private void taskUpdate(Map<String, Object> params) {
        taskMapper.updateByrwid(params);
    }


    /**
     * 抽象的基本方法。
     * @param task 参数 任务实体
     */
    protected abstract void taskUpdateRwzt(Map<String, Object> params);
}
我们注意这个类是一个抽象类 在这个类中我们使用了注解的方式来让框架帮我们自动把需要的实体注入到我们需要的地方 ,也就如上绿色的部分。同时在我们抽象类中会有一部分已经实现的方法对这个注入的类进行调用。

接下来我们看看抽象类的实现类

/**
 * 具体子类,提供审核通过的具体实现。
 * @author 
 *
 */
public class CheckPass extends RefreshBeverage {
    
    @Resource
    private TaskMapper taskMapper;
    
    @Override
    protected void taskUpdateRwzt(Map<String, Object> params) {
        // TODO Auto-generated method stub
        
    }

}
用过学过框架的都知道如果我们要在其他类中使用到这个抽象类中的方法的时候我们可以这样  比如下面的代码,我们在红色部分是注解注入 指定实体类在容器中的名字,绿色部分呢就是我们实际调用了

/**
 * 流程审批。
 * @author 
 */
@Repository
public class FlowServiceImpl implements IFlowService {

    @Resource(name="checkPass")
    private RefreshBeverage refreshBeverage;
    
    
    /**
     * 审批通过。
     * @param staff 客户实体
     * @param rwid 任务ID
     * @param op 具体操作
     */
    @Override
    public boolean auditPass(Map<String, Object> params) {
        
        Boolean result=refreshBeverage.prepareBeverageTemplate(params);
        
        
        return result;
    }
以上就是我们修改正确能够跑成功的实例了,但是,细心的大佬们应该会发现,在抽象类中我们注入了TaskMapper  在实现类中我们也注入了TaskMapper  ,可能你会想那是我在实现子类中要用的,或者说根本没必要这样,要不就直接把父类的注入
private TaskMapper taskMapper;
这个改成public的不就好了,这样继承的子类就不需要在申明一遍了  反正都会继承下来的。这样子确实有道理,因为呢这个确实是符合逻辑的,不过我也没试过,也没全部代码,我就不发表这个做法了,大佬们可以自己试试,然后告诉我哦(留下点问题以后碰到了记得测试再补充吧)

那么说到这里大家就应该知道我的解决办法了,那就是在子类中也同样

private TaskMapper taskMapper;

把这个注入进来呗。这样实现类中就有了这个申明,框架会帮我们注入,但是因为抽象类是不能实例化的,所以也是不会注入的,那个@resouce在抽象类中写不写都无所谓啦,反正容器是不会管的。

好啦,以上就是我的解决办法,大佬们要是有更好的建议希望评论留言,与我这小菜鸟交流交流呗。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值