请选择 进入手机版 | 继续访问电脑版

[java] 有关Java中的BeanInfo先容

[复制链接]
查看42 | 回复9 | 2021-9-12 21:00:59 | 显示全部楼层 |阅读模式
目次

1、JavaBean先容

维基百科

  1. JavaBean
复制代码
的定义:
  1. JavaBeans
复制代码
是Java中一种特殊 的类,可以将多个对象封装到一个对象(
  1. bean
复制代码
)中。特点是可序列化,提供无参构造器,提供getter方法和
  1. setter
复制代码
方法访问对象的属性。名称中的“
  1. Bean
复制代码
”是用于Java的可重用软件组件的惯用叫法。要成为
  1. JavaBean
复制代码
类,则必需依照 关于定名 、构造器、方法的特定规范。有了这些规范,才能有可以使用 、复用、替换 和毗连
  1. JavaBeans
复制代码
的工具。规范如下:

  • 有一个public的无参数构造器。
  • 属性可以通过
    1. get
    复制代码
    1. set
    复制代码
    1. is
    复制代码
    (可以替换
    1. get
    复制代码
    ,用在布尔型属性上)方法或依照 特定定名 规范的其他方法访问。
  • 可序列化。

以下为一个合法的JavaBean的定义:

  1. public class PersonBean implements java.io.Serializable {
  2. /**
  3. * name 属性(注意大小寫)
  4. */
  5. private String name = null;
  6. private boolean deceased = false;
  7. /** 无参构造器(没有参数) */
  8. public PersonBean() {
  9. }
  10. /**
  11. * name 属性的Getter方法
  12. */
  13. public String getName() {
  14. return name;
  15. }
  16. /**
  17. * name 属性的Setter方法
  18. * @param value
  19. */
  20. public void setName(final String value) {
  21. name = value;
  22. }
  23. /**
  24. * deceased 属性的Getter方法
  25. * 布尔型属性的Getter方法的不同形式(这里使用了is而非get)
  26. */
  27. public boolean isDeceased() {
  28. return deceased;
  29. }
  30. /**
  31. * deceased 属性的Setter方法
  32. * @param value
  33. */
  34. public void setDeceased(final boolean value) {
  35. deceased = value;
  36. }
  37. }
复制代码

有关Java中的BeanInfo先容

2、JavaBean的自省

用一个简单的

  1. SpringMVC
复制代码
用户登录的场景来形貌 一下
  1. JavaBean
复制代码
的自省,用户登录时间 ,前端表单传递的参数通常是一个如下Json字符串:

  1. {
  2. "username":"xxx",
  3. "password":"xxxx"
  4. }
复制代码

后端担当 表单的地方,通常可以使用 一个

  1. JavaBean
复制代码
  1. RequestBody
复制代码
的情势 吸收 参数:

  1. public void login(@RequestBody LoginRequest request){
  2. // Do login
  3. }
复制代码

此中 ,LoginRequest类似 于如下的格式:

  1. public class LoginRequest {
  2. public String getUsername() {
  3. return username;
  4. }
  5. public void setUsername(String username) {
  6. this.username = username;
  7. }
  8. public String getPassword() {
  9. return password;
  10. }
  11. public void setPassword(String password) {
  12. this.password = password;
  13. }
  14. private String username;
  15. private String password;
  16. }
复制代码

那么前端的

  1. Json
复制代码
怎样 映射到后端
  1. LoginRequest
复制代码
中的对应属性之上呢?可以看到
  1. LoginRequest
复制代码
中的字段都是private范例 ,无法直接设置字段值(反射固然 可以设置,但是并不合适),只能通过Setter方法举行 设置,但是程序怎么知道JavaBean有哪些Setter方法呢?此处就用到了
  1. JavaBean
复制代码
的内省机制。

有关Java中的BeanInfo先容

3、JavaBean内省工具Introspector

  1. Java bean
复制代码
的工具包中提供了java内省工具
  1. Introspector
复制代码
,该工具可以通过以下方法获取
  1. Java bean
复制代码
的内省结果
  1. BeanInfo
复制代码
(后文详细 先容 ),获取
  1. BeanInfo
复制代码
的流程如下图所示

  1. // 在Object类时候停止检索,可以选择在任意一个父类停止
  2. BeanInfo beanInfo = Introspector.getBeanInfo(JavaBeanDemo.class,Object.class);
复制代码

有关Java中的BeanInfo先容

4、JavaBean内省结果 BeanInfo

通过java的内省工具

  1. Introspector
复制代码
  1. getBeanInfo
复制代码
方法,我们可以获取一个
  1. JavaBean
复制代码
的内省
  1. BeanInfo
复制代码
获取到的BeanInfo包含以部属 性:

  • Bean的类干系 信息
  • Bean的变乱 信息
  • Bean的属性信息
  • Bean的方法信息
  • 额外属性信息
  • Component的图标

有关Java中的BeanInfo先容

5、内省结果 BeanInfo的范例

BeanInfo只是一个内省结果 的接口,Java中对该接口的实现有以下三种

  • ApplicationBeanInfo:
    1. Apple desktop
    复制代码
    干系 的
    1. JavaBean
    复制代码
    内省结果
  • ComponentBeanInfo:
    1. Java Awt
    复制代码
    组件的内省结果 ,如按钮等
  • GenericBeanInfo:通用的内省结果 ,JEE开发 中的内省结果 都为该范例

此外,

  1. Spring
复制代码
自定义了一个内省结果 范例 ,叫
  1. ExtendedBeanInfo
复制代码
,告急 用于辨认 返回值不为空的Setter方法。

有关Java中的BeanInfo先容

6、Spring的BeanUtils.copyProperties

  1. BeanUtils.copyProperties
复制代码
用户在两个对象之间举行 属性的复制,底层基于JavaBean的内省机制,通过内省得到拷贝源对象和目标 对象属性的读方法和写方法,然后调用对应的方法举行 属性的复制。以下为
  1. BeanUtils.copyProperties
复制代码
的流程

有关Java中的BeanInfo先容

  1. BeanUtils
复制代码
  1. JavaBean
复制代码
内省的一些机制举行 优化,到这里,大家有没有发现Java内省的一些缺点呢?

7、BeanUtils并发题目 优化

Java内省的结果 会缓存在

  1. ThreadGroupContext
复制代码
中,并且通过
  1. synchonrized
复制代码
关键字对缓存加锁(下图中的红框部分),导致同一个线程组中的线程无法并行内省。

有关Java中的BeanInfo先容

  1. Spring
复制代码
  1. BeanUtils
复制代码
在Java内省之上又添加了一层缓存,这层缓存使用
  1. ConcurrentHashMap
复制代码
实现,从而进步 了内省的服从 。

8、BeanUtils Setter属性辨认 优化

在Java默认的内省过程中,

  1. setter
复制代码
方法的返回值必须是
  1. null
复制代码
,假如 不是null的话,无法辨认 为有用 的
  1. JavaBean
复制代码
属性(下图中的红色部分),
  1. Spring
复制代码
自定义了一个
  1. BeanInfo ExtendedBeanInfo
复制代码
办理 了这个题目 。

有关Java中的BeanInfo先容

回到最初提到的

  1. spring.beaninfo.ignore
复制代码
,这个设置 用来忽略全部 自定义的BeanInfo类的搜刮 .

9、BeanUtils 性能测试

有关Java中的BeanInfo先容

可以看出:BeanUtils花费的时间约为直接复制的50倍以上。

  1. public class BeanUtilsPerformanceTest {
  2. public static void main(String[] args){
  3. // 预热虚拟机
  4. loopBeanUtils(100000);
  5. loopCopyByHand(100000);
  6. // 复制1万次的情况
  7. System.out.println("\nloop 10000 times:");
  8. loopBeanUtils(10000);
  9. loopCopyByHand(10000);
  10. // 复制1百万次的情况
  11. System.out.println("\nloop 1000000 times:");
  12. loopBeanUtils(1000000);
  13. loopCopyByHand(1000000);
  14. // 复制1亿次的情况
  15. System.out.println("\nloop 100000000 times:");
  16. loopBeanUtils(100000000);
  17. loopCopyByHand(100000000);
  18. }
  19. private static void loopBeanUtils(int loopTimes){
  20. TestBeanDemo source = new TestBeanDemo();
  21. TestBeanDemo target = new TestBeanDemo();
  22. long start = System.currentTimeMillis();
  23. for (int i=0;i<loopTimes;i++){
  24. BeanUtils.copyProperties(source,target);
  25. }
  26. System.out.println("BeanUtils cost times:"+String.valueOf(System.currentTimeMillis()-start));
  27. }
  28. private static void loopCopyByHand(int loopTimes){
  29. TestBeanDemo source = new TestBeanDemo();
  30. TestBeanDemo target = new TestBeanDemo();
  31. long start = System.currentTimeMillis();
  32. for (int i=0;i<loopTimes;i++){
  33. target.setField1(source.getField1());
  34. target.setField2(source.getField2());
  35. target.setField3(source.getField3());
  36. target.setField4(source.getField4());
  37. target.setField5(source.getField5());
  38. }
  39. System.out.println("Copy field one by one times:"+String.valueOf(System.currentTimeMillis()-start));
  40. }
  41. @Data
  42. private static class TestBeanDemo{
  43. private String field1 = UUID.randomUUID().toString();
  44. private String field2 = UUID.randomUUID().toString();
  45. private String field3 = UUID.randomUUID().toString();
  46. private String field4 = UUID.randomUUID().toString();
  47. private String field5 = UUID.randomUUID().toString();
  48. }
  49. }
复制代码

到此这篇关于有关Java中的BeanInfo先容 的文章就先容 到这了,更多干系 Java中的BeanInfo内容请搜刮 脚本之家从前 的文章或继续欣赏 下面的干系 文章渴望 大家以后多多支持脚本之家!


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

avatar 历史人物费 | 2021-9-13 06:09:46 | 显示全部楼层
支持一下!
回复

使用道具 举报

avatar 玲嘉婕嘉n | 2021-9-26 23:31:53 | 显示全部楼层
一口气看完了,我要下去回味回味了!
回复

使用道具 举报

avatar 您脱风云错 | 2021-10-3 04:50:00 | 显示全部楼层
不灌水就活不下去了啊!
回复

使用道具 举报

avatar 粘瓜莱 | 2021-10-4 09:46:15 | 显示全部楼层
读了admin楼主的帖子,顿时马桶就通了。。。
回复

使用道具 举报

avatar 立郎 | 2021-10-5 07:06:17 | 显示全部楼层
楼上的能详细介绍一下么?
回复

使用道具 举报

avatar 更强 | 2021-10-9 08:29:00 | 显示全部楼层
admin楼主的头像能辟邪啊!
回复

使用道具 举报

admin楼主的病已经好了百分之六十二了!
回复

使用道具 举报

这么版块的帖子越来越有深度了!
回复

使用道具 举报

收藏了,很不错的内容!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则