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

发布于 2024-11-28 10:35:53 字数 400 浏览 1 评论 0原文

我想扩展并注册我自己的函数,如下所示:

http: //static.springsource.org/spring/docs/3.0.x/reference/expressions.html 请参阅部分:6.5.11 函数。

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

在解析 xml 文件时,如何获取 spring 使用的“StandardEvaluationContext”对象的引用?如果没有那个弹簧就找不到我注册的功能。

谢谢,

亚伊尔

I want to extend and register my own function as detailed here:

http://static.springsource.org/spring/docs/3.0.x/reference/expressions.html see section: 6.5.11 Functions.

However, I wish to use this expression from a spring xml file and not in code as presented in the page.

How do I get a reference to the "StandardEvaluationContext" object used by spring while parsing my xml file? without having that spring can't find my registered function.

Thanks,

Yair

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

是你 2024-12-05 10:35:53

像这样的事情应该可以帮助您开始:

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 即可。

Something like this should get you started:

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);
                }
            });
        }

    }

}

Just register this bean in your application context.

总以为 2024-12-05 10:35:53

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

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);
        }

    }

}

}

您从 spring 文件中使用,如下所示:

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

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

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

So, the solution I found is:

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);
        }

    }

}

}

you use from the spring file like this:

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

in a bean that needs to use the getDbConfig function:

<property name="user" value="#{getDbConfig('username')}" />
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文