有关Java中的BeanInfo介绍
目录
- 1、JavaBean介绍
- 2、JavaBean的自省
- 3、JavaBean内省工具Introspector
- 4、JavaBean内省结果BeanInfo
- 5、内省结果BeanInfo的类型
- 6、Spring的BeanUtils.copyProperties
- 7、BeanUtils并发问题优化
- 8、BeanUtils Setter属性识别优化
- 9、BeanUtils 性能测试
1、JavaBean介绍 维基百科
JavaBean
的定义:JavaBeans
是Java中一种特殊的类,可以将多个对象封装到一个对象(bean
)中。特点是可序列化,提供无参构造器,提供getter方法和setter
方法访问对象的属性。名称中的“Bean
”是用于Java的可重用软件组件的惯用叫法。要成为JavaBean
类,则必需遵循关于命名、构造器、方法的特定规范。有了这些规范,才能有可以使用、复用、替代和连接JavaBeans
的工具。规范如下:- 有一个public的无参数构造器。
- 属性可以通过
get
、set
、is
(可以替代get
,用在布尔型属性上)方法或遵循特定命名规范的其他方法访问。 - 可序列化。
public class PersonBean implements java.io.Serializable {/*** name 属性(注意大小寫)*/private String name = null; private boolean deceased = false; /** 无参构造器(没有参数) */public PersonBean() {}/*** name 属性的Getter方法*/public String getName() {return name; }/*** name 属性的Setter方法* @param value*/public void setName(final String value) {name = value; }/*** deceased 属性的Getter方法* 布尔型属性的Getter方法的不同形式(这里使用了is而非get)*/public boolean isDeceased() {return deceased; }/*** deceased 属性的Setter方法* @param value*/public void setDeceased(final boolean value) {deceased = value; }}
文章图片
2、JavaBean的自省 用一个简单的
SpringMVC
用户登录的场景来描述一下JavaBean
的自省,用户登录时候,前端表单传递的参数通常是一个如下Json字符串:{ "username":"xxx", "password":"xxxx"}
后端接受表单的地方,通常可以使用一个
JavaBean
用RequestBody
的形式接收参数:public void login(@RequestBody LoginRequest request){// Do login}
其中,LoginRequest类似于如下的格式:
public class LoginRequest {public String getUsername() {return username; }public void setUsername(String username) {this.username = username; }public String getPassword() {return password; }public void setPassword(String password) {this.password = password; }private String username; private String password; }
那么前端的
Json
如何映射到后端LoginRequest
中的对应属性之上呢?可以看到LoginRequest
中的字段都是private类型,无法直接设置字段值(反射虽然可以设置,但是并不合适),只能通过Setter方法进行设置,但是程序怎么知道JavaBean有哪些Setter方法呢?此处就用到了JavaBean
的内省机制。文章图片
3、JavaBean内省工具Introspector
Java bean
的工具包中提供了java内省工具Introspector
,该工具可以通过以下方法获取Java bean
的内省结果BeanInfo
(后文详细介绍),获取BeanInfo
的流程如下图所示// 在Object类时候停止检索,可以选择在任意一个父类停止BeanInfo beanInfo = Introspector.getBeanInfo(JavaBeanDemo.class,Object.class);
文章图片
4、JavaBean内省结果BeanInfo 通过java的内省工具
Introspector
的getBeanInfo
方法,我们可以获取一个JavaBean
的内省BeanInfo
,获取到的BeanInfo包含以下属性:- Bean的类相关信息
- Bean的事件信息
- Bean的属性信息
- Bean的方法信息
- 额外属性信息
- Component的图标
文章图片
5、内省结果BeanInfo的类型 BeanInfo只是一个内省结果的接口,Java中对该接口的实现有以下三种:
- ApplicationBeanInfo:
Apple desktop
相关的JavaBean
内省结果 - ComponentBeanInfo:
Java Awt
组件的内省结果,如按钮等 - GenericBeanInfo:通用的内省结果,JEE开发中的内省结果都为该类型
Spring
自定义了一个内省结果类型,叫ExtendedBeanInfo
,主要用于识别返回值不为空的Setter方法。文章图片
6、Spring的BeanUtils.copyProperties
BeanUtils.copyProperties
用户在两个对象之间进行属性的复制,底层基于JavaBean的内省机制,通过内省得到拷贝源对象和目的对象属性的读方法和写方法,然后调用对应的方法进行属性的复制。以下为BeanUtils.copyProperties
的流程文章图片
BeanUtils
对JavaBean
内省的一些机制进行优化,到这里,大家有没有发现Java内省的一些缺点呢?7、BeanUtils并发问题优化 Java内省的结果会缓存在
ThreadGroupContext
中,并且通过synchonrized
关键字对缓存加锁(下图中的红框部分),导致同一个线程组中的线程无法并行内省。文章图片
Spring
的BeanUtils
在Java内省之上又添加了一层缓存,这层缓存使用ConcurrentHashMap
实现,从而提高了内省的效率。8、BeanUtils Setter属性识别优化 在Java默认的内省过程中,
setter
方法的返回值必须是null
,如果不是null的话,无法识别为有效的JavaBean
属性(下图中的红色部分),Spring
自定义了一个BeanInfo ExtendedBeanInfo
解决了这个问题。文章图片
回到最初提到的
spring.beaninfo.ignore
,这个配置用来忽略所有自定义的BeanInfo类的搜索.【有关Java中的BeanInfo介绍】
9、BeanUtils 性能测试
文章图片
可以看出:BeanUtils花费的时间约为直接复制的50倍以上。
public class BeanUtilsPerformanceTest {public static void main(String[] args){// 预热虚拟机loopBeanUtils(100000); loopCopyByHand(100000); // 复制1万次的情况System.out.println("\nloop 10000 times:"); loopBeanUtils(10000); loopCopyByHand(10000); // 复制1百万次的情况System.out.println("\nloop 1000000 times:"); loopBeanUtils(1000000); loopCopyByHand(1000000); // 复制1亿次的情况System.out.println("\nloop 100000000 times:"); loopBeanUtils(100000000); loopCopyByHand(100000000); }private static void loopBeanUtils(int loopTimes){TestBeanDemo source = new TestBeanDemo(); TestBeanDemo target = new TestBeanDemo(); long start = System.currentTimeMillis(); for (int i=0; i
到此这篇关于有关Java中的BeanInfo介绍的文章就介绍到这了,更多相关Java中的BeanInfo内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
推荐阅读
- 热闹中的孤独
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- JS中的各种宽高度定义及其应用
- 我眼中的佛系经纪人
- 《魔法科高中的劣等生》第26卷(Invasion篇)发售
- Android中的AES加密-下
- 事件代理
- 放下心中的偶像包袱吧
- C语言字符函数中的isalnum()和iscntrl()你都知道吗
- Java|Java OpenCV图像处理之SIFT角点检测详解