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
位。