Java&Spring日常笔记

作者: Java面试官 | 来源:发表于2019-03-17 00:22 被阅读2次

    系列文描述:

    hey,我是超级饭饭团,目前就职于广州某数字游戏公司,主攻java服务端。该系列是日常研发和个人学习中的笔记积累,目前定位是一周一次汇总分享(>▽<)。


    一、Spring系列

    最近在研究项目的基础组件,学习到了很多关于Spring方面比较深层次的用法,特做笔记记录。

    1.1 Spring中的InstantiationAwareBeanPostProcessor类的作用

    作用描述:
    InstantiationAwareBeanPostProcessor是一个抽象类,提供了抽象函数postProcessAfterInstantiation,在spring容器实例bean后,会扫描所有继承了InstantiationAwareBeanPostProcessor的类,并且调用其中被重写的函数postProcessAfterInstantiation,因此我们可以将容器实例化bean对象后要实现的业务放在该函数中。
    场景代码演示:


    演示demo1.png

    postProcessAfterInstantiation函数中携带的参数bean就是被实例化的对象,而beanName便是bean的名字(驼峰式),可以从我提供的源码看出我这边的业务是在bean对象被实例化后通过反射取出了bean对象的所有Field,并对bean对象做了一定的注入操作。
    而关于spring容器实例化bean后扫描所有继承了InstantiationAwareBeanPostProcessor的类的流程,这里提供一份bean的生命周期图,可以从bean的生命周期图看出流程:


    bean生命周期图片.png

    一句话总结:如果业务场景是在spring实例化bean后对bean做某些操作的,可以直接继承InstantiationAwareBeanPostProcessor类。

    1.2 Spring中的ReflectionUtils类的作用

    作用描述:
    在实际业务中,我们经常会遇见和Java反射操作相关的业务,可能不知道ReflectionUtils存在的话,处理方式就是自己写一套,然后各种try...catch...,而实际上ReflectionUtils类已经提供了这些操作,而且代码更加优化,具体demo可以看演示demo1提供的源码,如果不用该工具类的话我们肯定是先通过bean取出所有Field,然后再一个个遍历啥啥啥的,而通过该工具类明显就优化了很多,而且看起来也高大上逼格高。

    一句话总结:如果实际开发中需要做些反射的处理,那么可以直接使用spring的反射工具类ReflectionUtils,当然了,前提是要导入spring的maven包

    1.3 Spring中的转换器ConversionService

    作用描述:
    ConversionService是Spring提供的一套通用的转化方案,在需要进行类型转化的地方都可以用到。经常用到的地方是Properties,如在properties中的字符串是 list=1,2,3,4
    将之转化为java中的List<String>便是用到了ConversionService。
    场景代码演示:


    演示demo2.png

    StringToClassConverter是我自定义的转换器,作用是将字符串转换为对应的class


    演示demo2.png
    JsonToArrayConverter是我自定义的转换器,作用是json转换为数组对象。
    这两个转换器的区别是实现的接口不一样,一个是实现了Converter<String, Class>,另一个是实现了ConditionalGenericConverter。
    先说说ConditionalGenericConverter实现类,我们可以通过JsonToArrayConverter类的源码看出,其中有个getConvertibleTypes函数,该函数的作用是告诉spring容器这个转换器能够转换的原类型和目标类型,而matchs函数是我们用来定义使用该转换器条件的地方,从提供的源码可以看出只有源类型是String而目标类型是数组才可以使用该转换器。而具体的convert函数便是我们写具体转换业务的地方了。而第一个转换器StringToClassConverter,转换类型则直接放在了泛型类Converter<String, Class>中。
    具体使用步骤:
    配置.png
    注入.png
    使用.png

    操作流程如上所示:
    需要先在spring配置中告诉spring新增了转换器,而在具体业务类中注入ConversionService,再直接调用其中的convert函数即可,Spring会根据转换器上的的条件做筛选选择合适的转换器进行转换。其中的sourceType和targetType都要封装为TypeDescriptor,而content便是源数据。

    一句话总结:在遇见需要将某种类型的数据转换为其他类型的操作的业务中,可以考虑使用spring自身的转换器机制,操作流程是自定义转换器,配置注入,具体地方调用即可。

    1.4 spring中的ManagedList类

    在开发基础组件的时候,由于业务需要,查看了bean的生命周期,看到了Managed类型的数据结构,包括ManagedMap、ManagedSet等,了解到这是spring自定义的一种数据结构,主要用于封装BeanDefinition,对集合数据类型的具体解析有各自的解析方法实现,此处的BeanDefinition是spring自定义的类型,所有被spring容器管理的bean最后都是转换为BeanDefinition。

    二、Java系列
    2.1 通过反射取出Map<K, V>这种泛型结构中的参数类型

    作用描述:
    Map<Integer, Integer> hashMap = new HashMap<>();
    当Field指向该hashMap时,可以用Field.getGenericType() 取出Field的类型是Map<Integer, Integer>;
    可以用 xxx.getGenericType() intanceOf ParameterizedType 判断Field是否为泛型参数类型,所谓的泛型参数类型指的是Map<Integer, Integer> 或者 List<Integer> 这种;
    其次是可以通过 ((ParameterizedType)genericType).getActualTypeArguments() 取出Map中两个泛型的类型,如此处的便是Integer、Integer。

    2.2 反射中getFields()方法和getDeclaredFields ()方法的区别

    getFields():获得某个类的所有的公共(public)的字段,包括父类中的字段。
    getDeclaredFields():获得某个类的所有声明的字段,即包括public、private和proteced,但是不包括父类的字段。

    三、结尾说点什么

    目前正准备开源一个组件,会用到上面笔记上的所有知识点,到时候再做分享哈哈哈,然后没了(  ̄▽ ̄)((≧︶≦)


    系列博客可以关注公众号:

    公众号.jpg

    个人网站:http://myblog.lixifan.cn/

    相关文章

      网友评论

        本文标题:Java&Spring日常笔记

        本文链接:https://www.haomeiwen.com/subject/dqqymqtx.html