Spring-Bootjava&spring社区技术分享

Java&Spring日常笔记

2019-03-17  本文已影响2人  Java面试官

系列文描述:

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/

上一篇下一篇

猜你喜欢

热点阅读