@Value 属性 在 spring 组件中返回 null

@Value property is returning null in the spring component

我在 spring 引导程序中创建了一个验证器组件,并且在 application.properties 中保留了一个正则表达式。我已经使用 @Value 注释在我的组件中获取正则表达式的值,并且我在任何方法或构造函数之外编译模式,这给了我空指针异常,因为正则表达式当时没有获取它的值。但是当我将模式移动到某种方法时,它工作正常。这是为什么? 为什么即使对象是使用 @Component

创建的,@Value 也不起作用

看下面的代码:

返回 NullPointerException 的代码:

@Component
public class ValidString implements ConstraintValidator<ValidString, String> {

  @Value("${user.input.regex}")
  private String USER_INPUT_REGEX;

  private Pattern USER_INPUT_PATTERN = Pattern.compile(USER_INPUT_REGEX);

  @Override
  public boolean validate(String userInput, ConstraintValidatorContext constraintValidatorContext) {
    return USER_INPUT_PATTERN.matcher(userInput).find();
  }
}

代码工作正常:

@Component
public class ValidString implements ConstraintValidator<ValidString, String> {

  @Value("${user.input.regex}")
  private String USER_INPUT_REGEX;

  private Pattern USER_INPUT_PATTERN;

  @Override
  public boolean validate(String userInput, ConstraintValidatorContext constraintValidatorContext) {
    USER_INPUT_PATTERN = Pattern.compile(USER_INPUT_REGEX);
    return USER_INPUT_PATTERN.matcher(userInput).find();
  }
}

此外,如果您能解释为什么第一个不起作用而第二个起作用,那就太好了。

application.properties

user.input.regex = ^[a-zA-Z0-9/\-_ \s+]*$

模式 USER_INPUT_PATTERN 在 spring 进程之前。 class ValidString对象初始顺序为:->process field initial->constructor -> inject field 所以,当你使用1个代码时,它必须是空点,因为字段没有注入

字段初始值设定项(有问题的第一个示例)在 class 构造函数执行期间执行。 @Value 由 Spring 构造函数 returns 之后使用反射注入。这意味着您不能使用 @Value 注入值来初始化。

这个问题可以通过构造函数或setter注入来解决:

// Inject using constructor
@Component
public class ValidString implements ConstraintValidator<ValidString, String> {

  private Pattern USER_INPUT_PATTERN;

  @Autowired
  public ValidString(@Value("${user.input.regex}") String regex) {
    this.USER_INPUT_PATTERN = Pattern.compile(regex);
  }
// Inject using setter method
@Component
public class ValidString implements ConstraintValidator<ValidString, String> {

  private Pattern USER_INPUT_PATTERN;

  @Autowired
  private void setUserInputRegex(@Value("${user.input.regex}") String regex) {
    this.USER_INPUT_PATTERN = Pattern.compile(regex);
  }