多线程时Autowired自动注入问题

首先需要知道的是,容器中的组件,也就是你添加了诸如@Component , @Service , @Controller以及@Repository等等注解,在容器启动的时候是会扫描标注这些注解的类创建bean并放入容器中。

如果该类中的成员变量上使用了诸如@Autowired和@Resource注解时,容器将会找对应的bean并注入–依赖注入。

而在多线程实例中使用@Autowired注解有时得不到对象,为什么呢?

线程类实例如下:

@Component
public class TestThread extends Thread{

    private static final Logger log = LoggerFactory.getLogger(TestThread.class);

    @Autowired
    ISysBoundUserExtendDao boundUserExtendDao;

    @Autowired
    SysBoundUserMapper boundUserMapper;

    int pageBegin;

    int pageEnd;

    public TestThread( int pageEnd,int pageBegin) {
        super();
        this.pageEnd = pageEnd;
        this.pageBegin = pageBegin;
        log.debug("pageBegin : "+pageBegin+" , pageEnd : "+pageEnd);
    }
    public TestThread() {
        super();
    }
    public TestThread(ISysBoundUserExtendDao boundUserExtendDao, SysBoundUserMapper boundUserMapper, int pageEnd,
            int pageBegin) {
        super();
        this.boundUserExtendDao = boundUserExtendDao;
        this.boundUserMapper = boundUserMapper;
        this.pageEnd = pageEnd;
        this.pageBegin = pageBegin;
        log.debug("pageBegin : "+pageBegin+" , pageEnd : "+pageEnd);
    }

    public void run(){
        String result = "";
        Integer pageSize=1000;
        Map<String, Object> queryMap = new HashMap<>();
        for(int i=pageBegin;i<pageEnd;i++){
            queryMap.put("page", i);
            queryMap.put("pageSize", pageSize);
            log.debug("开始获取第"+i+"页用户...");
            List<SysBoundUser> boundUserList = boundUserExtendDao.getBoundUserList(queryMap);
            //...
            }
        }
}

使用了@Component和@Autowired注解。

此时创建多线程如下:

    @RequestMapping(value="checkUser2",produces="application/json;charset=utf-8")
    @ResponseBody
    public String checkUser2(){
        String result = "";
        TestThread testThread1 = new TestThread(4, 3);
        testThread1.start();
        TestThread testThread2 = new TestThread( 5, 4);
        testThread2.start();
        TestThread testThread3 = new TestThread(6, 5);
        testThread3.start();
        TestThread testThread4 = new TestThread(7, 6);
        testThread4.start();
        TestThread testThread5 = new TestThread(8, 7);
        testThread5.start();
        return result;
    }

会发现,在run()方法中boundUserExtendDao为null!!!

这是因为创建多线程时,是new的对象实例,非容器扫描时自动创建的对象实例!!!而你创建线程的时候并没有传入boundUserExtendDao。

如果获取的是容器创建的TestThread,那么肯定有mapper和dao:

这里写图片描述


那么如何在多线程中使用boundUserExtendDao呢?

答:创建的时候传入boundUserExtendDao实例!


实例如下,此时run方法中可以正确拿到mapper和dao:

@Controller
@RequestMapping("/test")
public class TestDataController {

    private static final Logger log = LoggerFactory.getLogger(TestDataController.class);

    @Autowired
    ISysBoundUserExtendDao boundUserExtendDao;

    @Autowired
    SysBoundUserMapper boundUserMapper;


    @RequestMapping(value="checkUser2",produces="application/json;charset=utf-8")
    @ResponseBody
    public String checkUser2(){
        String result = "";
        TestThread testThread1 = new TestThread( boundUserExtendDao, boundUserMapper,4, 3);
        testThread1.start();
        TestThread testThread2 = new TestThread( boundUserExtendDao, boundUserMapper,5, 4);
        testThread2.start();
        TestThread testThread3 = new TestThread(boundUserExtendDao, boundUserMapper, 6, 5);
        testThread3.start();
        TestThread testThread4 = new TestThread(boundUserExtendDao, boundUserMapper, 7, 6);
        testThread4.start();
        TestThread testThread5 = new TestThread(boundUserExtendDao, boundUserMapper, 8, 7);
        testThread5.start();
        return result;
    }

猜你喜欢

转载自blog.csdn.net/j080624/article/details/81013711