我已经在这里的旧帖子后面实现了一个枚举验证器。我想知道以下代码是否是线程安全的?我有许多不同的枚举,我需要使用这个验证器。这会产生任何问题吗?
@Documented
@Constraint(validatedBy = StringEnumerationValidator.class)
@Target({ElementType.FIELD,ElementType.ANNOTATION_TYPE,
ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@NotNull(message="Value must not be null.")
public @interface StringEnumeration {
String message() default "{com.xxx.bean.validation.constraints.StringEnumeration.message}";
Class<?>[] groups() default{};
Class<? extends Payload>[] payload() default{};
Class<? extends Enum<?>> enumClass();
}
public class StringEnumerationValidator implements
ConstraintValidator<StringEnumeration, String> {
private Set<String> AVAILABLE_ENUM_NAMES;
public static Set<String> getNamesSet(Class<? extends Enum<?>> e){
Enum<?>[] enums = e.getEnumConstants();
String[] names = new String[enums.length];
for (int i = 0; i < enums.length; i++) {
names[i] = enums[i].name();
System.out.println(enums.length);
System.out.println(enums[i]);
}
Set<String> mySet = new HashSet<String>(Arrays.asList(names));
return mySet;
}
@Override
public void initialize(StringEnumeration stringEnumeration) {
Class<? extends Enum<?>> enumSelected = stringEnumeration.enumClass();
AVAILABLE_ENUM_NAMES = getNamesSet(enumSelected);
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if (value == null) {
return true;
}
else {
return AVAILABLE_ENUM_NAMES.contains(value);
}
}
编辑:来源提及:
答案 0 :(得分:0)
是和否。严格来说,它不是线程安全的,因为您的initialize
方法可以由两个不同的线程同时调用。此方法写入AVAILABLE_ENUM_NAMES
变量,因此两个线程可能会相互干扰。
但是如果你确保每个实例只调用initialize
一次,那么在其他线程有权访问该实例之前,它是线程安全的,因为isValid
只读取集合并且不修改它
要确保只进行一次初始化,您应该在构造函数中执行:
public StringEnumeratorValidator(StringEnumeration stringEnumeration) {
Class<? extends Enum<?>> enumSelected = stringEnumeration.enumClass();
AVAILABLE_ENUM_NAMES = getNamesSet(enumSelected);
}
并删除intialize
方法。