Java SpEL:如何在中获取表达式的类型(不是它的值)
我试图使用拼写来获取表达式的类型,而不是实际的实例值。我认为这是不可能的,但我想把它扔出去 考虑:Java SpEL:如何在中获取表达式的类型(不是它的值),java,spring-el,Java,Spring El,我试图使用拼写来获取表达式的类型,而不是实际的实例值。我认为这是不可能的,但我想把它扔出去 考虑: public interface Foo { Integer getAge(); String getFamilyName(); String getGivenName(); Set<Integer> getSomeData(); Set<Baz> getBazez(); Baz getAnyBaz(); } pu
public interface Foo {
Integer getAge();
String getFamilyName();
String getGivenName();
Set<Integer> getSomeData();
Set<Baz> getBazez();
Baz getAnyBaz();
}
public interface Baz {
Integer getBat();
Integer getWhatever();
}
公共接口Foo{
整数getAge();
字符串getFamilyName();
字符串getGivenName();
设置getSomeData();
设置getBazez();
Baz getAnyBaz();
}
公共界面{
整数getBat();
整数getWhatever();
}
一些测试
@Test
public void testNestedMemberDataType() throws Exception {
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext context = new StandardEvaluationContext();
Expression exp = parser.parseExpression("anyBaz.bat");
Class<?> valueType = exp.getValueType(context);
assertEquals(Integer.class,valueType);
}
@Test
public void testNestedMemberDataTypeSet() throws Exception {
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext context = new StandardEvaluationContext();
// this is not valid spell syntax but I would like to do this
// to indicate the type inside the collection
Expression exp = parser.parseExpression("bazez[*].bat");
Class<?> valueType = exp.getValueType(context);
assertEquals(Integer.class,valueType);
}
@测试
public void testNestedMemberDataType()引发异常{
ExpressionParser=new SpelExpressionParser();
EvaluationContext=新标准EvaluationContext();
表达式exp=parser.parseExpression(“anyBaz.bat”);
类valueType=exp.getValueType(上下文);
assertEquals(Integer.class,valueType);
}
@试验
public void testNestedMemberDataTypeSet()引发异常{
ExpressionParser=new SpelExpressionParser();
EvaluationContext=新标准EvaluationContext();
//这是无效的拼写语法,但我想这样做
//指示集合中的类型的步骤
表达式exp=parser.parseExpression(“bazez[*].bat”);
类valueType=exp.getValueType(上下文);
assertEquals(Integer.class,valueType);
}
我最终实际实现了它:
@Override
public Class<?> getDeclaredTypeFor(String attribute) {
Class<?> finalType = entityType;
List<String> nestings = Arrays.asList(attribute.split("\\."));
PropertyDescriptor d = null;
Iterator<String> iter = nestings.iterator();
while (iter.hasNext()) {
String nesting = iter.next();
d = BeanUtils.getPropertyDescriptor(finalType, nesting);
if (d == null) {
Set<Class> allTypes = allTypesFor(finalType, new LinkedHashSet<>());
d = allTypes.stream().map(t -> BeanUtils.getPropertyDescriptor(t, nesting)).filter(p -> p != null).findFirst().orElse(null);
if (d == null)
break;
}
if (iter.hasNext() && isTypeACollection(d.getReadMethod().getGenericReturnType())) {
finalType = getGenericType(d.getReadMethod().getGenericReturnType(), true);
} else {
finalType = d.getPropertyType();
}
}
return d == null ? null : finalType;
}
private Class getGenericType(Type t, boolean isCollection) {
Class clazz;
if (isCollection) {
Type type = ((ParameterizedType) t).getActualTypeArguments()[0];
if (type instanceof WildcardType) {
type = ((WildcardType) type).getUpperBounds()[0];
} else if(type instanceof TypeVariable) {
type = ((TypeVariable) type).getBounds()[0];
}
clazz = (Class) type;
} else if (t instanceof Class) {
clazz = (Class) t;
} else {
throw new RuntimeException("Don't know how to handle " + t.getClass());
}
return clazz;
}
private boolean isTypeACollection(Type t) {
boolean isPossible = t instanceof ParameterizedType;
if (isPossible)
isPossible = Collection.class.isAssignableFrom((Class) ((ParameterizedType) t).getRawType());
return isPossible;
}
private static Set<Class> allTypesFor(Class c, Set<Class> types) {
types.add(c);
Class superclass = c.getSuperclass();
if (superclass != null)
allTypesFor(superclass, types);
for (Class iFace : c.getInterfaces()) {
allTypesFor(iFace, types);
}
return types;
}
@覆盖
公共类getDeclaredTypeFor(字符串属性){
类finalType=entityType;
列表嵌套=Arrays.asList(attribute.split(“\\”);
PropertyDescriptor d=null;
迭代器iter=nestings.Iterator();
while(iter.hasNext()){
字符串嵌套=iter.next();
d=BeanUtils.getPropertyDescriptor(finalType,嵌套);
如果(d==null){
将allTypes=allTypes设置为(finalType,newlinkedhashset());
d=allTypes.stream().map(t->BeanUtils.getPropertyDescriptor(t,嵌套)).filter(p->p!=null).findFirst().orElse(null);
如果(d==null)
打破
}
if(iter.hasNext()&&isTypeACollection(d.getReadMethod().getGenericReturnType()){
finalType=getGenericType(d.getReadMethod().getGenericReturnType(),true);
}否则{
finalType=d.getPropertyType();
}
}
返回d==null?null:finalType;
}
私有类getGenericType(类型t,boolean isCollection){
课堂讨论;
if(isCollection){
类型类型=((ParameteredType)t).getActualTypeArguments()[0];
if(类型instanceof WildcardType){
类型=((通配符类型)类型).getUpperBounds()[0];
}else if(类型instanceof TypeVariable){
类型=((TypeVariable)类型).getBounds()[0];
}
clazz=(类)类型;
}else if(类的t实例){
clazz=(类)t;
}否则{
抛出新的RuntimeException(“不知道如何处理”+t.getClass());
}
回击声;
}
私有布尔值isTypeACollection(类型t){
布尔值isPossible=t参数化类型的实例;
如果(可能的话)
isPossible=Collection.class.isAssignableFrom((class)((ParameterizedType)t.getRawType());
返回是可能的;
}
专用静态集合所有类型(c类,集合类型){
类型。添加(c);
Class superclass=c.getSuperclass();
if(超类!=null)
所有类型(超类、类型);
对于(类iFace:c.getInterfaces()){
所有类型(如有,类型);
}
返回类型;
}
您可能可以通过使用改进getGenericType
位。