使用Spring Expression Language编译Pattern对象

时间:2019-01-08 21:24:27

标签: java spring spring-el

是否可以使用SpEL通过属性文件中的正则表达式来编译Pattern对象?我试图避免每次调用此类中的方法时都编译正则表达式。我可以使用@Value只是将正则表达式设置为String,然后使用具有getter的Pattern对象,并让getter进行null检查,然后仅在这种情况下编译Patter。但是似乎应该有一种更简洁的方法来完成此操作。

我希望替换为这个

    @Value("${some.regex}")
    private String regex;

    private Pattern PATTERN = null;

    public Pattern getPattern() {
        if (PATTERN == null)
            PATTERN = Pattern.compile(regex);
        return PATTERN;
    }
与此类似:
    @Value("#{Pattern.compile('${some.regex}')}")
    private Pattern pattern;

4 个答案:

答案 0 :(得分:2)

类似这样的东西:

    @Value("#{T(java.util.regex.Pattern).compile('${some.regex}')}")

重点是使用T运算符来访问static方法。请参阅参考手册中的更多内容:https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#expressions-types

答案 1 :(得分:1)

我建议您对@Value进行工程设计以提供正则表达式模式,然后在某处的初始化方法中验证正则表达式正确。

这给您带来一些明显的好处:

  • 您可以清楚地了解正在执行的操作以及操作方式(SpEL可能是 wee 有点神秘的东西)
  • 您有能力可靠,轻松地对其进行测试
  • 您可以在开发时调试它

我的解决方法是这样。

@Component
public class FooClass {
    @Value("${some.regex}")
    private String regex;

    private Pattern pattern;

    @PostConstruct
    public void init() {
        pattern = Pattern.compile(regex);
    }
    // rest of code here
}

答案 2 :(得分:1)

尽管Artem的答案恰好显示了您的要求,但在这种情况下,前面的场注入(which has quite a few problems)也可以提供一个干净的解决方案:

private Pattern pattern;

@Value("${some.regex}")
public void setRegex(String regex) {
    this.pattern = Pattern.compile(regex);
}

答案 3 :(得分:0)

我这样做的方式是创建自己的验证注释。

@Documented
@Retention(RUNTIME)
@Target({METHOD,FIELD})
@Constraint(validatedBy=PropertyPatternValidator.class)
public @interface PropertyPattern {
    String property();
    String message() default "{validator.propertypattern}";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

验证器实现

public class PropertyPatternValidator implements ConstraintValidator<PropertyPattern, CharSequence> {

private Map<String, Pattern> patterns = new HashMap<>();
private Pattern pattern;

@Override
public void initialize(PropertyPattern propPattern) {
    String property = propPattern.property();
    pattern = patterns.computeIfAbsent(property, prop -> {
        Properties applicationProps = (Properties) ApplicationContextProvider.getApplicationContext()
                .getBean("applicationProps");
        String p = applicationProps.getProperty(prop);
        return Pattern.compile(p);
    });
}

@Override
public boolean isValid(CharSequence inputToValidate, ConstraintValidatorContext ctx) {
    CharSequence input = inputToValidate != null ? inputToValidate : "";
    Matcher m = pattern.matcher(input);
    return m.matches();
}
}

用法:

@PropertyPattern(property ="pattern.account")
private String accountNumber;

然后,只要pattern.account在属性文件中,并将其设置为有效的正则表达式,它将起作用。