理解java注解三

好了,之前的理解java注解二理解java注解一,已经讲了java注解的一些基础知识,下面,我们来看看具体的应用。

之前的 讲解都比较简单,许多伙伴看了之后都会有些不满意,你这写的啥呀?和没写差不多啊,没啥干货!却是,我之前写的都是十分浅显的应用,稍稍看过一点java注解的都能做出来。

其实,许多伙伴感觉注解神奇,想要了解注解,可又不知道从何下手,注解看起来好神秘,好复杂,好难用。比如:看到同事在类上、方法上或者属性上加了一个注解,就可以进行权限的校验,参数的校验,甚至是属性的处理,猛然一看,云里雾里,好高大上!其实,你仔细剖开注解的面纱,就会发现,原来这个也没有太深入啊!

接下来,我就说一说特殊对象统一封装时,注解的使用。

首先,创建一个注解,标识这个对象是有附件的,需要递归(下钻)获取附件对象(开始水代码)。

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AttachAnnotion {

}

然后就直接进入主题,创建一个附件对象AttachInfoList,标识一个上传附件的地方,其中包含refId与附件集合attachInfos:

@Data
public class AttachInfoList extends BaseVO{

    private String refId ;

    private List<AttachVO> attachVOList;
}

下面创建一个页面对象PageTestVO

@Data
public class PageTestVO extends BaseVO {

    private String pageName;

    @AttachAnnotion
    private ParagraphVO paragraphVO;

    //单个文件
    private AttachInfoList attachInfo;

    //多个文件
    private List<AttachInfoList> attachInfos;

    private String imageRefId;

}

其中paragraphVO是段落,其中也有文件信息

@Data
public class ParagraphVO extends BaseVO {

    private String name ;

    /**
     * 附件
     */
    private AttachInfoList attachInfoLists;
    
}

对象创建完毕,下面开始通过反射和注解处理问题,代码已经注释的比较详细了,伙伴们看下哈~

package com.example.demo;

import com.alibaba.fastjson.JSON;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class AnnoTest {
    public static void main(String[] args) {
        PageTestVO base = new PageTestVO();
        List<AttachInfoList> attachInfos = new ArrayList<>();

        // 单个--- attachInfo
        AttachInfoList attachInfo = new AttachInfoList();
        AttachVO test111 = new AttachVO("111", "test111");
        List<AttachVO> list1 = new ArrayList<>();
        list1.add(test111);
        attachInfo.setAttachVOList(list1);
        attachInfo.setRefId("test111");
        base.setAttachInfo(attachInfo);

        //多个 ----- attachInfos
        AttachInfoList attachInfo2 = new AttachInfoList();
        AttachVO test222 = new AttachVO("222", "test222");
        List<AttachVO> list2 = new ArrayList<>();
        list2.add(test222);
        attachInfo2.setAttachVOList(list2);

        AttachInfoList attachInfo3 = new AttachInfoList();
        AttachVO test333 = new AttachVO("333", "test333");
        List<AttachVO> list3 = new ArrayList<>();
        list3.add(test333);
        attachInfo3.setAttachVOList(list3);

        List<AttachInfoList> attachInfoLists23 = new ArrayList<>();
        attachInfoLists23.add(attachInfo2);
        attachInfoLists23.add(attachInfo3);
        base.setAttachInfos(attachInfoLists23);

        //注解嵌套 -----paragraphVO
        AttachInfoList attachInfo4 = new AttachInfoList();
        AttachVO test444 = new AttachVO("444", "test444");
        List<AttachVO> list4 = new ArrayList<>();
        list4.add(test444);
        attachInfo4.setAttachVOList(list4);
        ParagraphVO paragraphVO = new ParagraphVO();
        paragraphVO.setAttachInfoLists(attachInfo4);
        base.setParagraphVO(paragraphVO);

        dealAttachInfo(base, attachInfos);

        System.out.println("数据附件提取:" + JSON.toJSON(attachInfos));
    }
    
    public static <T> void dealAttachInfo(T base, List<AttachInfoList> attachInfos) {
        // 为空不处理
        if (base == null) {
            return;
        }
        // 对象是AttachInfoList,直接处理
        if (base instanceof AttachInfoList) {
            attachInfos.add((AttachInfoList) base);
            return;
        }
        // 集合遍历处理
        if (base instanceof List) {
            Iterator it = ((List) base).iterator();
            while (it.hasNext()) {
                dealAttachInfo(it.next(), attachInfos);
            }
        } else {
            //处理逻辑
            Class<?> baseClass = base.getClass();
            //遍历属性处理
            Field[] fields = baseClass.getDeclaredFields();
            try {
                for (Field field : fields) {
                    String name = field.getName(); //属性名称
                    String getMethodName = "get" + name.substring(0, 1).toUpperCase() + name.substring(1); //获取该属性的方法名
                    Method method = baseClass.getMethod(getMethodName);  //获取该属性的方法
                    Object obj = method.invoke(base);   //该属性类型及值
                    //这个属性是AttachInfoList,那么直接封装禁attachInfos
                    if (obj == null) continue;
                    if (obj instanceof AttachInfoList) {
                        attachInfos.add((AttachInfoList) obj);
                    } else if (obj instanceof List && ((List) obj).size() > 0 && ((List) obj).get(0) instanceof AttachInfoList) {
                        attachInfos.addAll((List) obj);
                    } else {
                        //如果不是,继续查找注解,看看是否需要继续下钻
                        AttachAnnotion attachAnnotion = field.getDeclaredAnnotation(AttachAnnotion.class);  //是否有文件注解
                        if (attachAnnotion != null) {
                            if (obj instanceof List) {
                                for (Object ob : (List) obj) {
                                    dealAttachInfo(ob, attachInfos);
                                }
                            } else {
                                dealAttachInfo(obj, attachInfos);
                            }
                        }
                    }
                }
            } catch (Exception e) {
                System.out.println("出现错误:" + e.getMessage() + "   location:" + e.getLocalizedMessage());
            }
        }
    }
}

给大家看下运行的结果:

com.example.demo.AnnoTest
数据附件提取:[{"attachVOList":[{"name":"test444","attachId":"444"}]},{"refId":"test111","attachVOList":[{"name":"test111","attachId":"111"}]},{"attachVOList":[{"name":"test222","attachId":"222"}]},{"attachVOList":[{"name":"test333","attachId":"333"}]}]

直接把代码全部复制过来了,这里我要说几点:一、这个逻辑我处理复杂了,其实不会出现这个:

   //多个文件
    private List<AttachInfoList> attachInfos;

因为AttachInfoList本身就是一个附件的集合,其中有一个关联的id,如果有多个,明显需要创建多个AttachInfoList,而不是再次集合到一起。代码中有些东西可以删掉,当然不处理也不会出问题,只是逻辑不走而已。

二、有些伙伴发现,哎?我不是用注解,只用反射,也能搞定啊!没错!是的,不使用注解也可以层层递归,获取到附件的信息,但是由于没有注解的标识,你会递归每个对象,不管这个对象有没有文件,这样,对性能来说就不太友好了,哪怕耗费的性能并不多。

三、这个其实只是把附件抽出来而已,如果要保存,还需要组装数据处理,注意refId 的关联创建等等,同时查询的时候似乎也可以对文件批量处理哦,有兴趣的小伙伴可以试下。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笔下天地宽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值