添加Spring工具类
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import java.util.Map;
@Component
public class SpringUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if (SpringUtil.applicationContext == null) {
SpringUtil.applicationContext = applicationContext;
}
}
//获取applicationContext
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
//通过name获取 Bean.
public static Object getBean(String name) {
return applicationContext.getBean(name);
}
//通过class获取Bean.
public static <T> T getBean(Class<T> clazz) {
return applicationContext.getBean(clazz);
}
//通过name,以及Clazz返回指定的Bean
public static <T> T getBean(String name, Class<T> clazz) {
return applicationContext.getBean(name, clazz);
}
//通过Class返回指定的BeanMap
public static <T> Map<String, T> getBeansOfType(Class<T> clazz) {
return applicationContext.getBeansOfType(clazz);
}
}
以 RestUtil工具类 使用 RestTemplate(Spring管理的Bean) 为例
1. Spring注入RestTemplate
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
@Component
public class RestConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
2. 创建Rest工具类
import org.springframework.web.client.RestTemplate;
public class RestUtil {
private static RestTemplate restTemplate;
static {
// 使用SpringUtil 设置 RestUtil 的静态属性 restTemplate
restTemplate = SpringUtil.getBean(RestTemplate.class);
}
private RestUtil() {
}
public static <T> T get(String url, Class<T> responseType) {
return restTemplate.getForObject(url, responseType);
}
}
3. 测试
单元测试代码
@Test
public void restTest(){
String url = "https://ccdcapi.alipay.com/validateAndCacheCardInfo.json?cardBinCheck=true&cardNo={{银行卡号}}";
Map map = RestUtil.get(url, Map.class);
System.out.println(JSON.toJSONString(map));
}
单元测试结果
image
4. 为什么在静态代码块中设置restTemplate?
SpringBoot 启动完成时,RestUtil 没有实例化,RestUtil 的静态方法也未被调用过。所以在调用静态方法或实例化时,一定可以通过 SpringUtil 获取到 Spring Bean。然后 RestUtil 中的 restTemplate 只需要初始化一次,而静态代码块的代码只会执行一次,正好满足需求。
关于类的代码块、静态代码块、构造器的加载时机测试代码
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class RestTest {
// 实例化测试
@Test
void test1() {
System.out.println("-------------------");
new A();
System.out.println("-------------------");
new A();
System.out.println("-------------------");
}
// 静态方法调用测试
@Test
void test2() {
System.out.println("-------------------");
A.a();
System.out.println("-------------------");
A.a();
System.out.println("-------------------");
}
}
class B {
{
System.out.println("父类非静态代码块");
}
static {
System.out.println("父类静态代码块");
}
public B() {
System.out.println("父类构造器");
}
}
class A extends B {
{
System.out.println("子类非静态代码块");
}
static {
System.out.println("子类静态代码块");
}
public A() {
System.out.println("子类构造器");
}
public static void a() {
System.out.println("执行方法a");
}
}
test1结果
test2结果
网友评论