线程中使用@Autowired注入
场景
多多线程同时访问接口,测试接口稳定性
工具RestTemplate
使用springboot自带http调用
线程类实现Callable
代码实现
一下是通过@Autowired注入的方式
public static void main(String[] arge){
Future p = pool.submit(new RunnableUtil(url, urlSuffixInsertNews, body1, tokenDto.getToken()));
JSONObject resJson = JSONObject.parseObject(p.get().toString());
}
线程类
package com.yx.util.runnable;
import com.alibaba.fastjson.JSONObject;
import com.yx.util.httpClient.ClientUtil;
import lombok.Data;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Data
public class RunnableUtil implements Callable {
@Autowired
private ClientUtil clientUtil;
private String url;
private Map<String, Object> json;
private String urlSuffix;
private String token;
public RunnableUtil(String url, String urlSuffix, Map<String, Object> json, String token){
super();
this.url = url;
this.urlSuffix = urlSuffix;
this.json = json;
this.token = token;
}
@Override
public Object call() throws Exception {
String res = clientUtil.doPost(url, urlSuffix, json, token);
return res;
}
}
请求方法
package com.yx.util.httpClient;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.DefaultUriBuilderFactory;
import java.util.Map;
@Component
public class ClientUtil {
@Autowired
private RestTemplate restTemplate;
/**
* @param url ip+端口 :127.0.0.1:8080/
* @param urlSuffix 请求地址
* @param body 请求参数 json格式
* @param token 请求头参数
* */
public static String doPost(String url, String urlSuffix, Map<String, Object> body, String token){
DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(url);
factory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.TEMPLATE_AND_VALUES);
restTemplate.setUriTemplateHandler(factory);
HttpHeaders headers = new HttpHeaders();
headers.add("token", token);
HttpEntity<Map> requestEntity = new HttpEntity<>(body, headers);
ResponseEntity<String> responseEntity = restTemplate.postForEntity(urlSuffix,requestEntity , String.class);
if(responseEntity.getStatusCode().is2xxSuccessful()){
System.out.println(responseEntity.getBody());
}else {
System.out.println(responseEntity.getStatusCode().value()+ "和" + responseEntity.getBody());
}
return responseEntity.getBody();
}
}
也就是线程@通过Autowired注入的方式调用会一直出现空指针异常
解决方案就是在晚上找一个获取bean的方法
@Component
public class SpringContextUtil implements ApplicationContextAware {
/**
* 上下文对象实例
*/
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContextUtil.applicationContext = applicationContext;
}
/**
* 获取applicationContext
*
* @return
*/
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* 通过name获取 Bean.
*
* @param name
* @return
*/
public static Object getBean(String name) {
if (applicationContext == null){
throw new RuntimeException("applicationContext注入失败");
}
return getApplicationContext().getBean(name);
}
/**
* 通过class获取Bean.
*
* @param clazz
* @param <T>
* @return
*/
public static <T> T getBean(Class<T> clazz) {
if (applicationContext == null){
throw new RuntimeException("applicationContext注入失败");
}
return getApplicationContext().getBean(clazz);
}
/**
* 通过name,以及Clazz返回指定的Bean
*
* @param name
* @param clazz
* @param <T>
* @return
*/
public static <T> T getBean(String name, Class<T> clazz) {
if (applicationContext == null){
throw new RuntimeException("applicationContext注入失败");
}
return getApplicationContext().getBean(name, clazz);
}
}
使用
RestTemplate restTemplate = SpringContextUtil.getBean(ClientUtil.class)