Browse Source

Add: SpringUtil.getBean(TypeReference<T>)
添加Spring工具类静态方法,通过类型参考(TypeReference)获取带泛型参数的Bean,同时添加了一个小的单元测试

dejavuhuh 5 years ago
parent
commit
741c0cfe1a

+ 22 - 0
hutool-extra/src/main/java/cn/hutool/extra/spring/SpringUtil.java

@@ -1,10 +1,16 @@
 package cn.hutool.extra.spring;
 package cn.hutool.extra.spring;
 
 
+import cn.hutool.core.lang.ParameterizedTypeImpl;
+import cn.hutool.core.lang.TypeReference;
 import cn.hutool.core.util.ArrayUtil;
 import cn.hutool.core.util.ArrayUtil;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationContextAware;
 import org.springframework.context.ApplicationContextAware;
+import org.springframework.core.ResolvableType;
 import org.springframework.stereotype.Component;
 import org.springframework.stereotype.Component;
 
 
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Arrays;
 import java.util.Map;
 import java.util.Map;
 
 
 /**
 /**
@@ -73,6 +79,22 @@ public class SpringUtil implements ApplicationContextAware {
 		return applicationContext.getBean(name, clazz);
 		return applicationContext.getBean(name, clazz);
 	}
 	}
 
 
+    /**
+     * 通过类型参考返回带泛型参数的Bean
+     *
+     * @param reference 类型参考,用于持有转换后的泛型类型
+     * @param <T> Bean类型
+     * @return 带泛型参数的Bean
+     */
+	@SuppressWarnings("unchecked")
+	public static <T> T getBean(TypeReference<T> reference) {
+		ParameterizedType parameterizedType = (ParameterizedType) reference.getType();
+		Class<T> rawType = (Class<T>) parameterizedType.getRawType();
+		Class<?>[] genericTypes = Arrays.stream(parameterizedType.getActualTypeArguments()).map(type -> (Class<?>) type).toArray(Class[]::new);
+		String[] beanNames = applicationContext.getBeanNamesForType(ResolvableType.forClassWithGenerics(rawType, genericTypes));
+		return applicationContext.getBean(beanNames[0], rawType);
+	}
+
 	/**
 	/**
 	 * 获取指定类型对应的所有Bean,包括子类
 	 * 获取指定类型对应的所有Bean,包括子类
 	 *
 	 *

+ 23 - 0
hutool-extra/src/test/java/cn/hutool/extra/spring/SpringUtilTest.java

@@ -1,5 +1,7 @@
 package cn.hutool.extra.spring;
 package cn.hutool.extra.spring;
 
 
+import cn.hutool.core.lang.TypeReference;
+import cn.hutool.core.map.MapUtil;
 import lombok.Data;
 import lombok.Data;
 import org.junit.Assert;
 import org.junit.Assert;
 import org.junit.Test;
 import org.junit.Test;
@@ -8,6 +10,11 @@ import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
 
+import java.lang.reflect.Type;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
 @RunWith(SpringJUnit4ClassRunner.class)
 @RunWith(SpringJUnit4ClassRunner.class)
 @SpringBootTest(classes = {SpringUtil.class, SpringUtilTest.Demo2.class})
 @SpringBootTest(classes = {SpringUtil.class, SpringUtilTest.Demo2.class})
 //@Import(cn.hutool.extra.spring.SpringUtil.class)
 //@Import(cn.hutool.extra.spring.SpringUtil.class)
@@ -20,6 +27,14 @@ public class SpringUtilTest {
 		Assert.assertEquals("test", testDemo.getName());
 		Assert.assertEquals("test", testDemo.getName());
 	}
 	}
 
 
+	@Test
+	public void getBeanWithTypeReferenceTest() {
+		Map<String, Object> mapBean = SpringUtil.getBean(new TypeReference<Map<String, Object>>() {});
+		Assert.assertNotNull(mapBean);
+		Assert.assertEquals("value1", mapBean.get("key1"));
+		Assert.assertEquals("value2", mapBean.get("key2"));
+	}
+
 	@Data
 	@Data
 	public static class Demo2{
 	public static class Demo2{
 		private long id;
 		private long id;
@@ -32,5 +47,13 @@ public class SpringUtilTest {
 			demo.setName("test");
 			demo.setName("test");
 			return demo;
 			return demo;
 		}
 		}
+
+		@Bean(name="mapDemo")
+		public Map<String, Object> generateMap() {
+			HashMap<String, Object> map = MapUtil.newHashMap();
+			map.put("key1", "value1");
+			map.put("key2", "value2");
+			return map;
+		}
 	}
 	}
 }
 }