Elegant Method of Getting Generic Information in Spring
- 2021-07-10 19:58:26
- OfStack
Brief introduction
Spring source code is a big treasure house, we can meet most tools can be found in the source code, so the author's open source mica is completely based on Spring for basic enhancement, and does not repeat wheels. What I want to share today is the elegant acquisition of generics in Spring.
Get generics
Self-analysis
Our previous processing method, the code source is vjtools (Jiangnan White).
/**
* Through reflection , Obtain Class The type of generic parameter of the parent class declared in the definition .
*
* Note that generics must be defined at the parent class . This is the only 1 Can be obtained from generics through reflection Class The place of the instance .
*
* If it cannot be found , Return Object.class.
*
* Such as public UserDao extends HibernateDao<User,Long>
*
* @param clazz clazz The class to introspect
* @param index the Index of the generic declaration, start from 0.
* @return the index generic declaration, or Object.class if cannot be determined
*/
public static Class getClassGenericType(final Class clazz, final int index) {
Type genType = clazz.getGenericSuperclass();
if (!(genType instanceof ParameterizedType)) {
logger.warn(clazz.getSimpleName() + "'s superclass not ParameterizedType");
return Object.class;
}
Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
if ((index >= params.length) || (index < 0)) {
logger.warn("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: "
+ params.length);
return Object.class;
}
if (!(params[index] instanceof Class)) {
logger.warn(clazz.getSimpleName() + " not set the actual class on superclass generic parameter");
return Object.class;
}
return (Class) params[index];
}
ResolvableType Tools
Since Spring 4.0, ResolvableType tool has been added to Spring, which makes it easier to return generic information.
First, let's look at the official example:
private HashMap<Integer, List<String>> myMap;
public void example() {
ResolvableType t = ResolvableType.forField(getClass().getDeclaredField("myMap"));
t.getSuperType(); // AbstractMap<Integer, List<String>>
t.asMap(); // Map<Integer, List<String>>
t.getGeneric(0).resolve(); // Integer
t.getGeneric(1).resolve(); // List
t.getGeneric(1); // List<String>
t.resolveGeneric(1, 0); // String
}
Detailed description
Construct to get generic information of Field
ResolvableType.forField(Field)
Construct to get generic information of Method
ResolvableType.forMethodParameter(Method, int)
Construct to get generic information of parameters returned by methods
ResolvableType.forMethodReturnType(Method)
Construct to get generic information of construction parameters
ResolvableType.forConstructorParameter(Constructor, int)
Construct to get generic information of a class
ResolvableType.forClass(Class)
Construct to get generic information of a type
ResolvableType.forType(Type)
Construct to get generic information of an instance
ResolvableType.forInstance(Object)
For more use of Api, please see ResolvableType java doc: https://docs.spring.io/spring-framework/docs/current/api/org/springframework/core/ResolvableType.html