美文网首页
通过套娃,让你在自己new出的对象中使用容器bean

通过套娃,让你在自己new出的对象中使用容器bean

作者: 小明_d19e | 来源:发表于2021-08-12 13:40 被阅读0次

参考这个

https://blog.csdn.net/ZHJUNJUN93/article/details/78560700?utm_source=blogxgwz17
@Component
public class DealQueueThread implements Runnable {

    private static DealQueueThread dealQueueThread;
    @Autowired
    BuyGoodService buyGoodService;
    @Autowired
    BuyOrdersService buyOrdersService;
    @Autowired
    JedisPool jedisPool;

    private Jedis jedis;

    private BuyQueue<BuyRequest> buyqueue;

    public static boolean excute = false;//线程的默认执行标志为未执行,即空闲状态

    public DealQueueThread() {

    }

    public DealQueueThread(BuyQueue<BuyRequest> buyqueue) {
        this.buyqueue = buyqueue;
        jedis = dealQueueThread.jedisPool.getResource();
    }

    @PostConstruct
    public void init() {
        dealQueueThread = this;
        dealQueueThread.buyGoodService = this.buyGoodService;
        dealQueueThread.buyOrdersService = this.buyOrdersService;
        dealQueueThread.jedisPool = this.jedisPool;
    }

    @Override
    public void run() {
        try {
            excute = true;//修改线程的默认执行标志为执行状态
            //开始处理请求队列中的请求,按照队列的FIFO的规则,先处理先放入到队列中的请求
            while (buyqueue != null && buyqueue.size() > 0) {
                BuyRequest buyreq = buyqueue.take();//取出队列中的请求
                dealWithQueue(buyreq);//处理请求
            }
        } catch (InterruptedException e) {
            BaseLog.error("DealQueueThread:", e);
        } finally {
            excute = false;
        }
    }

    public synchronized void dealWithQueue(BuyRequest buyreq) {
        try {
            //为了尽量确保数据的一致性,处理之前先从redis中获取当前抢购商品的剩余数量
            int residue = Integer.valueOf(jedis.get("residue" + buyreq.getGood_id()));
            if (residue < 1) {//如果没有剩余商品,就直接返回
                buyreq.setResponse_status(3);
                return;
            }
            //如果有剩余商品,先在redis中将剩余数量减一,再开始下订单
            jedis.decr("residue" + buyreq.getGood_id());
            //将数据库中将剩余数量减一,这一步处理可以在队列处理完成之后一次性更新剩余数量
            dealQueueThread.buyGoodService.minusResidue(buyreq.getGood_id());

            //处理请求,下订单
            BuyOrders bo = new BuyOrders();
            bo.setGood_id(buyreq.getGood_id());
            bo.setUser_id(buyreq.getUser_id());
            int order_id = dealQueueThread.buyOrdersService.insert(bo);
            BuyOrders orders = dealQueueThread.buyOrdersService.getById(order_id);
            buyreq.setOrder_id(order_id);//订单id
            buyreq.setBuyOrders(orders);//订单信息
            buyreq.setResponse_status(1);//处理完成状态
        } catch (Exception e) {
            buyreq.setResponse_status(2);//异常状态
            BaseLog.error("DealQueueThread dealWithQueue:", e);
        }
    }

}
 

用的时候DealQueueThread dealQueue = new DealQueueThread(buyqueue);
从上面可见@Component,说明该类通过扫描,生成了bean,并且通过注入,将容器里的bean注入了进来,现在问题是这个类是个多线程处理,他用的时候是需要new的,不归spring管理,但是他通过一个静态数据成员 private static DealQueueThread dealQueueThread;把spring注入的bean又给保存起来了.
这个方法是挺好的,试用范围广,一般是你需要new的时候但是又想用spring的bean,比如activiti流程图的监听器.
否则就得自己在构造函数里,用spring工具类找到相应bean再赋值,相对麻烦点.

相关文章

网友评论

      本文标题:通过套娃,让你在自己new出的对象中使用容器bean

      本文链接:https://www.haomeiwen.com/subject/sbrlbltx.html