由於最近在寫的項目需要使用到多線程提升效率,但是我在線程中調用注入對象的時候卻發現始終爲空,下面是我如何解決這個問題的方法。
原因分析
new thread對象不在spring容器中,所以無法通過@Autoware獲去到spring的bean對象。
解決辦法
爲了解決這個問題,有以下幾個思路
- 在聲明成員變量的時候,將其定義爲static的。這樣都可以調用到
- 可以通過手動的方式獲取
- 可以通過參數直接傳入
重點講解第二個方法
//創建一個工具類來獲取Bean:
package com.test.configs;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class BeanContext implements ApplicationContextAware {
private static ApplicationContext applicationContext;
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
BeanContext.applicationContext = applicationContext;
}
public static ApplicationContext getApplicationContext(){
return applicationContext;
}
@SuppressWarnings("unchecked")
public static <T> T getBean(String name) throws BeansException {
return (T)applicationContext.getBean(name);
}
public static <T> T getBean(Class<T> clz) throws BeansException {
return (T)applicationContext.getBean(clz);
}
}
//創建thread
package com.test.handler;
import com.test.configs.BeanContext;
import com.test.service.TestService;
import com.test.model.User;
public class TestHandler implements Runnable {
private User user;
private TestService testService;
@Override
public void run() {
this.testService= BeanContext.getApplicationContext().getBean(TestService.class);
User user=testService.queryUserById(11);
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
//其他service調用
ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("upFinancial-pool-%d").build();
ExecutorService pool = new ThreadPoolExecutor(corePoolSize, maxPoolSize,
6000L, TimeUnit.MILLISECONDS,
new LinkedBlockingDeque<Runnable>(1024), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());
UpFinancialContractHandler handler=new UpFinancialContractHandler();
handler.setUser(user);
pool.execute(handler);