多线程时Autowired自动注入问题

简介: 多线程时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;
    }


目录
相关文章
|
安全 API Windows
3.1 DLL注入:常规远程线程注入
动态链接库注入技术是一种特殊的技术,它允许在运行的进程中注入DLL动态链接库,从而改变目标进程的行为。DLL注入的实现方式有许多,典型的实现方式为远程线程注入,该注入方式的注入原理是利用了`Windows`系统中提供的`CreateRemoteThread()`这个API函数,该函数第四个参数是准备运行的线程,我们将`LoadLibrary()`函数填入其中,这样就可以执行远程进程中的`LoadLibrary()`函数,进而将我们自己准备的DLL加载到远程进程空间中执行,DLL在被装载后则会自动执行初始化部分。
124 0
|
9月前
|
网络协议 安全 API
9.9 Windows驱动开发:内核远程线程实现DLL注入
在笔者上一篇文章`《内核RIP劫持实现DLL注入》`介绍了通过劫持RIP指针控制程序执行流实现插入DLL的目的,本章将继续探索全新的注入方式,通过`NtCreateThreadEx`这个内核函数实现注入DLL的目的,需要注意的是该函数在微软系统中未被导出使用时需要首先得到该函数的入口地址,`NtCreateThreadEx`函数最终会调用`ZwCreateThread`,本章在寻找函数的方式上有所不同,前一章通过内存定位的方法得到所需地址,本章则是通过解析导出表实现。
123 0
9.9 Windows驱动开发:内核远程线程实现DLL注入
|
10月前
|
Java Spring
Spring在多线程中bean的注入问题
Spring在多线程中bean的注入问题
105 0
|
网络协议 安全 API
驱动开发:内核远程线程实现DLL注入
在笔者上一篇文章`《内核RIP劫持实现DLL注入》`介绍了通过劫持RIP指针控制程序执行流实现插入DLL的目的,本章将继续探索全新的注入方式,通过`NtCreateThreadEx`这个内核函数实现注入DLL的目的,需要注意的是该函数在微软系统中未被导出使用时需要首先得到该函数的入口地址,`NtCreateThreadEx`函数最终会调用`ZwCreateThread`,本章在寻找函数的方式上有所不同,前一章通过内存定位的方法得到所需地址,本章则是通过解析导出表实现。
4924 0
|
Shell
驱动开发:内核ShellCode线程注入
还记得`《驱动开发:内核LoadLibrary实现DLL注入》`中所使用的注入技术吗,我们通过`RtlCreateUserThread`函数调用实现了注入DLL到应用层并执行,本章将继续探索一个简单的问题,如何注入`ShellCode`代码实现反弹Shell,这里需要注意一般情况下`RtlCreateUserThread`需要传入两个最重要的参数,一个是`StartAddress`开始执行的内存块,另一个是`StartParameter`传入内存块的变量列表,而如果将`StartParameter`地址填充为`NULL`则表明不传递任何参数,也就是只在线程中执行`ShellCode`代码,利用
354 1
|
安全 Java
为什么直接通过 @Autowired 注入的 HttpServletRequest 没有线程安全的问题
我们在各个地方注入依赖时,大多数情况下都是单例的。为什么直接通过 @Autowired 注入的 HttpServletRequest 没有线程安全的问题呢?带着这个问题我做了如下笔记。
214 0
|
Windows
突破SESSION 0 隔离的远线程注入
在Windows XP,Windows Server 2003以及更早的版本中,第一个登录的用户以及Windows的所有服务都运行在Session 0上,这样的做法导致用户使用的应用程序可能会利用Windows的服务程序提升自身的权限,为此,在后续的Windows版本中,引入了一种隔离机制,普通应用程序已经不再session 0中运行。
140 0
|
前端开发 安全 Java
Spring注入的成员属性HttpServletRequest是线程安全的吗?【享学Spring MVC】(上)
Spring注入的成员属性HttpServletRequest是线程安全的吗?【享学Spring MVC】(上)
|
XML 安全 前端开发
Spring注入的成员属性HttpServletRequest是线程安全的吗?【享学Spring MVC】(下)
Spring注入的成员属性HttpServletRequest是线程安全的吗?【享学Spring MVC】(下)
Spring注入的成员属性HttpServletRequest是线程安全的吗?【享学Spring MVC】(下)
|
安全 API Go
我的免杀之路:远程线程注入
远程线程注入技术能实现在Windows系统下进程的隐藏。其主要核心在于一个Windows API函数CreateRemoteThread,通过它可以在另外一个进程中注入一个线程并执行。
962 0
我的免杀之路:远程线程注入