Java 反射的使用场景
个人对 Java 反射这块,还不透,先把项目里用到反射的场景以及简单的原理和实现整理,肯定不全,等待时间添加新的理解。反射在运行时操作对象,当配合注解,动态代理等一同使用,使得开发更专注业务。
看到网上有个例子,也是讲反射的,说 Java IDE 的代码自动提示即采用了反射来提示类中的成员,也有人指出说大部分是采用语法树来实现的。
实体属性拷贝
从数据库读取的 UserDo 实体,字段很多,但不需要都返回前端,于是定义了一个 UserVo,将 UserVo 的字段设置成 UserDo 里对应字段的值。代码里很多这样模板式的对应赋值,如果都 new UserVo() 在赋值,阅读性很差,于是出现了很多框架,比如 Spring 的 BeanUtils,Apache 的 BeanUtils 等。将属性 copy 简化成一句代码。
1 | copyProperties(Object source, Object target); |
项目里可以对其简单封装下,搞一个 CopyUtils 工具类,在需要 copy 的地方,直接像如下调用
1 | UserDo userDo = ... |
如果我来写 copyProperties 的实现,大致思路如下:获取源对象的所有字段,获取待赋值对象的所有字段,通过遍历,如果源对象的属性名 equals 目标对象的属性名,则获取源对象属性的值,并赋给目标对象该属性。
1 | public static <S, T> T copyProperties(S s, Class<T> t) throws IllegalAccessException, InstantiationException { |
Spring 的 BeanUtils 的 copyProperties 思路类似,处理的比较细致,使用了 PropertyDescriptor 来读写属性。
依赖注入(反射 + 注解)
半年前整理过一篇注解入门的文章,很基础,现在回看还可以,贴下链接:https://mjd507.github.io/2018/03/02/Java-Annotation/ 当反射配合上注解,使用的场景就更多了。
单元测试的 @Test 注解,相当于测试的一个入口,使用反射来解析,获取到测试的方法,从而 invoke 该方法。
Spring 的依赖注入。@Component,@Autowired 等。以及 Google 的 Guice 依赖注入框架。
1
2
3
4
5
6// 最常见的 @Autowired ,可以基于成员变量注入,基于构造方法注入,基于 set 方法注入
private MessageService service;
// 如果不利用注解和反射去注入,那就需要手动 new 对象
private MessageService service = new MessageServiceImpl();
Aop (反射 + 注解 + 动态代理)
面向切面编程,将横跨不同模块的代码抽离出来,让模块更加内聚,开发更专注于业务本身。在修改或新增功能方面,通过切面都可以很好的支持。Aop 离不开动代理,JDK 默认提供了一种动态代理 ,Spring Aop 支持两种模式的动态代理,JDK Proxy 或 cglib,常用于用户鉴权,日志,事务处理等场景。
Title: Java 反射的使用场景
Author: mjd507
Date: 2018-09-01
Last Update: 2024-01-27
Blog Link: https://mjd507.github.io/2018/09/01/Java-Reflection-Scenes/
Copyright Declaration: This station is mainly used to sort out incomprehensible knowledge. I have not fully mastered most of the content. Please refer carefully.