xml文件中的Spring表达式语言扩展

时间:2011-08-07 07:47:18

标签: java spring spring-el

我想扩展并注册我自己的功能,详见此处:

http://static.springsource.org/spring/docs/3.0.x/reference/expressions.html参见章节:6.5.11函数。

但是,我希望从spring xml文件中使用此表达式,而不是在页面中显示的代码中。

如何在解析my xml文件时获得spring使用的“StandardEvaluationContext”对象的引用?没有那个春天找不到我的注册功能。

谢谢,

亚伊尔

2 个答案:

答案 0 :(得分:2)

这样的事情应该让你开始:

public class FunctionRegistrationBean implements BeanFactoryAware{

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        if (beanFactory instanceof ConfigurableBeanFactory) {
            ConfigurableBeanFactory cbf = (ConfigurableBeanFactory) beanFactory;
            cbf.setBeanExpressionResolver(new StandardBeanExpressionResolver(){
                @Override
                protected void customizeEvaluationContext(
                        StandardEvaluationContext evalContext) {
                    evalContext.registerFunction("someName", someMethod);
                    evalContext.registerFunction("someOtherName", someOtherMethod);
                }
            });
        }

    }

}

只需在您的应用程序上下文中注册此bean。

答案 1 :(得分:1)

所以,我找到的解决方案是:

public class DBCustomExpressionRegistration implements BeanFactoryAware {

@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
    if (beanFactory instanceof ConfigurableBeanFactory) {
        ConfigurableBeanFactory cbf = (ConfigurableBeanFactory) beanFactory;
        cbf.setBeanExpressionResolver(new StandardBeanExpressionResolver(){
            @Override
            protected void customizeEvaluationContext(
                    StandardEvaluationContext evalContext) {
                evalContext.addMethodResolver(new InfraReflectiveMethodResolver());
            }
        });
    }

}

public String getDbConfig(String param){
    Configuration configuration  = ConfigurationFactory.getConfiguration();             
    @SuppressWarnings("unchecked")
    Iterator<String> keys = configuration.getKeys();
    while(keys.hasNext()){
        String key = keys.next();
        String value = configuration.getString(key);
        String tempKey = "database.*."+param;
        if (key.matches(tempKey)){
            return value;
        }
    }

    throw new IllegalArgumentException("could find pattern for: database.<string>" + param);
}


private class InfraReflectiveMethodResolver extends ReflectiveMethodResolver {

    @Override
    public MethodExecutor resolve(EvaluationContext context, Object targetObject, String name, List<TypeDescriptor> argumentTypes) throws AccessException {

        if ("getDbConfig".equals(name)){
            return new DBMethodExecutor();
        }
        return super.resolve(context, targetObject, name, argumentTypes);
    }

}

private class DBMethodExecutor implements MethodExecutor {

    @Override
    public TypedValue execute(EvaluationContext context, Object target, Object... arguments) throws AccessException {

        try {
            return new TypedValue(getDbConfig((String)arguments[0]), new TypeDescriptor(new MethodParameter(DBCustomExpressionRegistration.class.getDeclaredMethod("getDbConfig",new Class[] { String.class }), -1)));
        }
        catch (Exception ex) {
            throw new AccessException("Problem invoking method: getDbConfig" , ex);
        }

    }

}

}

你从弹簧文件中使用如下:

<bean id="dbCustomExpressionRegistration" class="com.db.util.DBCustomExpressionRegistration"/>

在需要使用getDbConfig函数的bean中:

<property name="user" value="#{getDbConfig('username')}" />