自定义注解及使用

定义一个自定义注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface SelfAnnotation {
    String value() default "";
}

定义一个类使用自定义注解

public class TestAnno {
    @SelfAnnotation(value = "hello world")
    public void sayHello() {

    }
}

简单解析自定义注解

                //通过反射创建对象  需要类的全路径
                Class<?> aClass = Class.forName("com.zhuoyue.TestAnno");
                //aClass.getAnnotation()获取类上的注解
                //获取所有方法的注解
                Arrays.stream(aClass.getDeclaredMethods()).forEach(method -> {
                    SelfAnnotation annotation = method.getAnnotation(SelfAnnotation.class);
                    System.out.println(annotation.value());
                });

项目中解析自定义注解(动态从/target中获取类名的全路径)

    @Test
    public void test2() throws Exception {
        //拼接资源路径
        String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
                ClassUtils.convertClassNameToResourcePath("com.zhuoyue.test") + "/**/*.class";
        //创建一个一个资源路径解析器
        ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
        //创建一个源数据读取工厂
        MetadataReaderFactory readerfactory = new CachingMetadataReaderFactory(resourcePatternResolver);
        //遍历资源解析器的所有资源
        Arrays.stream(resourcePatternResolver.getResources(pattern)).forEach(resource -> {
            //用于读取类信息
            MetadataReader reader = null;
            try {
                //通过源数据读取工厂创建一个reader对象
                reader = readerfactory.getMetadataReader(resource);
                //通过reader流读取对应资源类名(全路径)
                String className = reader.getClassMetadata().getClassName();
                //通过反射创建对象
                Class<?> aClass = Class.forName(className);
                //aClass.getAnnotation()获取类上的注解
                //获取所有方法的注解
                Arrays.stream(aClass.getDeclaredMethods()).forEach(method -> {
                    SelfAnnotation annotation = method.getAnnotation(SelfAnnotation.class);
                    System.out.println(annotation.value());
                });
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });
    }

借助自定义注解给属性赋值

import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.springframework.util.ObjectUtils;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * @author wjj
 */
@Data
public class BillDto {

    /**
     * 主单据
     */
    @TestNew(value = "aa")
    private String main;
    /**
     * 单据明细
     */
    private String detail;


    public static void main(String[] args) {
			//创建一个dto
            BillDto billDto = new BillDto();
			//假设数据来源是map集合
            Map<String, Object> map = new HashMap<>();
            map.put("aa","hello");
            Arrays.stream(billDto.getClass().getDeclaredFields())
                    //获取有注解的属性
					.filter(field -> !ObjectUtils.isEmpty(field.getAnnotation(TestNew.class)))
                    .forEach(field -> {
					//设置私有属性可以被访问修改
                        field.setAccessible(true);
						//获取该属性属性名或注解重命名
                        String key = StringUtils.isBlank(field.getAnnotation(TestNew.class).value())?field.getName():field.getAnnotation(TestNew.class).value();
						//获取数据
                        Object o = map.get(key);
                        try {
						//给该属性赋值
                            FieldUtils.writeField(field,billDto,o);
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        }
                    });
            System.out.println(billDto);
    }
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    public @interface TestNew {
        String value() default "";
    }

}