1.定义注解类
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyCustomAnnotation {
String name();
SupportEnum[] supportEnum();
}
其中,name表示该注解对应的类名称,supportEnum表示支持的项目。
2 .定义枚举类
public enum SupportEnum {
EMAIL,
PHONE_NUMBER,
ADDRESS
}
定义了三个枚举值,分别表示EMAIL、PHONE_NUMBER和ADDRESS三个项目。
3.定义注解处理器类
public class MyCustomAnnotationProcessor implements ApplicationContextAware, InitializingBean {
private ApplicationContext applicationContext;
private Map<SupportEnum, Validator> validatorMap = new HashMap<>();
@Override
public void afterPropertiesSet() throws Exception {
Map<String, Validator> validatorBeanMap = applicationContext.getBeansOfType(Validator.class);
for (Validator validator : validatorBeanMap.values()) {
SupportEnum supportEnum = validator.support();
validatorMap.put(supportEnum, validator);
}
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public void validate(Object obj) {
Class<?> clazz = obj.getClass();
if (clazz.isAnnotationPresent(MyCustomAnnotation.class)) {
MyCustomAnnotation annotation = clazz.getAnnotation(MyCustomAnnotation.class);
String name = annotation.name();
SupportEnum[] supportEnums = annotation.supportEnum();
for (SupportEnum supportEnum : supportEnums) {
if (validatorMap.containsKey(supportEnum)) {
Validator validator = validatorMap.get(supportEnum);
if (!validator.validate(obj)) {
throw new IllegalArgumentException(name + " is not valid, " + supportEnum.name() + " validation failed.");
}
}
}
}
}
}
该处理器类实现了ApplicationContextAware和InitializingBean接口,用于获取应用上下文和初始化校验器。其中,ApplicationContextAware接口用于获取应用上下文,InitializingBean接口用于初始化校验器。校验器是通过获取应用上下文中的所有Validator类型的Bean,并按照支持的项目存储在一个Map中。
在validate方法中,首先判断被校验的类是否有MyCustomAnnotation注解,如果有,则获取注解中的name和supportEnum属性。然后遍历supportEnum数组,对于每一个项目,从validatorMap中获取对应的Validator,并进行校验。如果校验失败,则抛出异常。
4.定义校验器接口和实现类
public interface Validator<T> {
boolean validate(T obj);
SupportEnum support();
}
@Component
public class EmailValidator implements Validator<MyClass> {
@Override
public boolean validate(MyClass obj) {
// email validation logic
return true;
}
@Override
public SupportEnum support() {
return SupportEnum.EMAIL;
}
}
@Component
public class PhoneNumberValidator implements Validator<MyClass> {
@Override
public boolean validate(MyClass obj) {
// phone number validation logic
return true;
}
@Override
public SupportEnum support() {
return SupportEnum.PHONE_NUMBER;
}
}
@Component
public class AddressValidator implements Validator<MyClass> {
@Override
public boolean validate(MyClass obj) {
// address validation logic
return true;
}
@Override
public SupportEnum support() {
return SupportEnum.ADDRESS;
}
}
定义了三个校验器类,分别用于对EMAIL、PHONE_NUMBER和ADDRESS三个项目进行校验。这些类需要实现Validator接口,并实现其中的validate方法和support方法。其中,validate方法用于实现具体的校验逻辑,support方法用于返回该校验器支持的项目。
5.在需要进行校验的类上添加注解
@MyCustomAnnotation(name = "MyClass", supportEnum = {SupportEnum.EMAIL, SupportEnum.PHONE_NUMBER, SupportEnum.ADDRESS})
public class MyClass {
private String email;
private String phoneNumber;
private String address;
// getters and setters
}
在MyClass类上添加了MyCustomAnnotation注解,并配置了name为"MyClass",supportEnum为{SupportEnum.EMAIL, SupportEnum.PHONE_NUMBER, SupportEnum.ADDRESS},表示该类需要对EMAIL、PHONE_NUMBER和ADDRESS三个项目进行校验。
6.调用校验方法进行校验
MyClass obj = new MyClass();
obj.setEmail("example@example.com");
obj.setPhoneNumber("1234567890");
obj.setAddress("123 Main St.");
MyCustomAnnotationProcessor processor = new MyCustomAnnotationProcessor();
processor.validate(obj);
在需要进行校验的地方,创建一个MyClass对象,并设置email、phoneNumber和address属性。然后创建一个MyCustomAnnotationProcessor对象,并调用其validate方法进行校验。如果校验失败,则会抛出IllegalArgumentException异常。
通过自定义注解和注解处理器,我们可以方便地实现复杂的校验逻辑,并且可以通过校验器的方式实现校验逻辑的复用。