JavaBean

作者: 善倾 | 来源:发表于2018-09-01 23:55 被阅读0次

    此前在学习 C# 时,讲到的三层模型,显示层、业务层以及持久层,他们之间是通过和数据库表一一对应的一个模型类( Model 类)对象传送数据的。但是在 Java 技术体系中,这种模型类叫做 JavaBean ,而且范围更广,现在思维需要转换过来了。

    Java 技术栈中 JavaBean 可以分为表单Bean 、结果Bean 和逻辑Bean,逻辑Bean 又可以分为业务Bean 和 持久Bean 。这里的业务Bean 的概念也就是三层模型中的业务层,持久Bean 就是三层模型中的持久层。表单Bean 是专门针对显示层页面收集过来的数据,结果Bean 则是和数据库中表属性一一对应的 Java 类,用来存放和数据库存储相关的 Java 类。

    使用 JavaBean 的好处是使代码组件化,提高代码复用性,便于后期开发和维护等等啦,知道有这么回事就好了。

    表单Bean

    在 JSP 页面中使用表单Bean 可以让 HTML 代码和 Java 代码分离,能够提高代码重用性,便于开发和维护。JSP 页面中是通过 JSP 动作来操作这种表单Bean 的。

    Java 中对于表单Bean 有以下几个要求:

    • 必须有包声明语句,web 应用中必须有包声明,这一点不同于纯 JavaSE 项目,可以有默认包
    • 表单Bean 必须声明为 public ,供所有类使用
    • 必须要显示提供 public 的无参构造方法,因为 JSP 页面通过 JSP 动作能够创建表单Bean 对象,就是利用了这个无参构造方法。
    • 属性必须私有,提供规则命名的 get/set 方法来操作属性。这里一方面是面向对象封装特性的要求,另一方面也是因为 JSP 动作使用反射技术来调用方法实现的赋值操作的要求,取值拿到对象的引用直接取值就可以了,不需要利用到反射。

    在 JSP 页面中使用 JavaBean

    JSP 页面中书写 Java 代码真的是件非常痛苦的事情,编写困难、复用性差、不可维护等等。所以,JSP 设计者提供了一种通过 JSP 动作就能够使用 JavaBean 的方法给程序员使用,在小型项目中用的还是挺爽的。

    为什么说是在小型项目中用的爽呢?因为即便通过 JSP 动作可以避免在 JSP 页面中嵌入 Java 代码,但是仍然分工不明确,JSP 既做页面展示又做逻辑业务处理,一旦业务过于复杂,仍然会很让人头疼,后期很难扩展和维护。

    web 应用中需要用到的 .class 字节码文件都统一放在 WEB-INF/classes 目录下,JSP 页面中可以通过全名找到此字节码文件。但是一旦 Java 类做出了修改,仅仅重新编译成字节码文件是不够的,需要重启 Tomcat 才能够将其加载到内存中去。

    但每次修改源码就需要重启服务器,那简直是太繁琐了,另一种方式是在 conf/server.xml 文件中的该项目的虚目录配置<Context />中添加一个reloadable = "true"的属性,如下:<Context path="/tw" docBase = "/opt/tomcat/testWeb" reloadable = "true"。当 reloadable 属性设置为 true 时,Tomcat 在运行状态下会主动监视 WEB-INF/classes 和 WEB-INF/lib 下的 .class 文件的改动,一旦有文件改动,立即将 web 应用重新加载到内存中去。此方法会消耗 Tomcat 资源,所以仅在开发阶段使用,实际部署项目时应该将 reloadable 属性设置为 false 。

    使用<jsp:useBean/>创建表单Bean 实例对象

    使用方式如下,所谓的 JSP 动作/标签其实也就是 JSP 设计者提供给程序员使用的一种看起来更简洁、能够少写几行代码的一种符号而已。JSP 引擎还是会把这些标签转换成原生 Java 代码的,查看源码即可证明。

    <jsp:useBean id = "simple" class = "cn.mldn.lxh.demo.SimpleBean" scope ="page"/>

    上述标签在 JSP 页面转换成对应的 xxx_jsp.java 文件后的源码是什么样的呢?看看源码就知道它背后到底都做了什么工作了。对应源码如下:

    cn.mldn.lxh.demo.SimpleBean simple = null;
          simple = (cn.mldn.lxh.demo.SimpleBean) _jspx_page_context.getAttribute("simple", javax.servlet.jsp.PageContext.PAGE_SCOPE);
          if (simple == null){
            simple = new cn.mldn.lxh.demo.SimpleBean();
            _jspx_page_context.setAttribute("simple", simple, javax.servlet.jsp.PageContext.PAGE_SCOPE);
          }
    

    <jsp:useBean/>完成的功能是,创建一个 SimpleBean 对象,对象引用名为 simple ,并把他们作为属性名和属性值存进 page 内置对象中去。内部实现逻辑是,首先去 page 对象里面找是否有名为 Simple 的属性,如果有就直接取出来用,如果没有就直接 new 出一个对象,并设定到 page 对象的属性区中。Bean 对象的创建并没有利用到反射机制,能 new 为什么要用反射呢?毕竟反射很消耗资源对吧?这种先查询再创建对象的方式在其他范围内的对象中就很有效,比如 request 、session 和 appliaction。点击这里查看内置对象的四个作用范围笔记

    「英文时间」:scope n. 范围

    scope 属性后跟的是四个作用域对象的一个,Bean 对象作为内置对象的属性存在,它的生命周期同内置对象的一样,这是为了让Bean 对象能够在不同页面中传递数据。

    使用<jsp:setProperty/>给Bean 对象赋值

    这种 JSP 动作有以下使用几种方式:

    //自动匹配,给所有的Bean对象的所有属性进行赋值
    <jsp:setProperty name="simple" property="*"/>
    //给Bean对象的指定属性赋值
    <jsp:setProperty name="simple" property="age"/>
    //使用指定的参数给Bean对象指定的属性赋值
    <jsp:setProperty name="simple" property="age" param="age"/>
    //使用指定的value值给Bean对象指定的属性赋值
    <jsp:setProperty name="simple" property="age" value="21"/>
    

    这里所谓的赋值操作,就是从 request 对象中拿到浏览器传送过来的参数和参数值,然后给 Bean 对象对应的属性赋值。这里内部源码调用机制比较复杂,但是它的思想其实就是,先从内置对象属性区中拿到对应的对象,利用 reqeust 对象的 getParameterNames() 方法得到 Enumeration 对象,然后依次遍历表单传送过来的参数,并使用方法反射给对应的属性进行赋值。

    这里有两个需要注意的点是:

    • 表单中传送过来的参数是 String 类型的,但是 Bean对象中的属性如果是 int 类型的,JSP 标签会自动调用Integer.praseInt(String str)方法转换成 int 类型的数据,这很好。但是如果传送过来的数据不符合规则,如23a,在将其转换成 int 类型数据的时候,会产生 NumberFormatException 异常,这是此标签的一大缺点,框架中已经修复了此问题。
    • 如果表单文本框中没有输入数据,则是以空字符串""的形式传送到request 对象中时,此标签并没有把空字符串作为一个 value 值放到 Bean对象的属性中去,而是不进行任何赋值操作。这是第二个缺点,框架中当然也做了修复。

    使用<jsp:getProperty/>从内置对象中拿到属性值

    使用方式如下:<jsp:getProperty name="simple"> property="age"/>

    它内部的实现机制是,先从内置对象中拿到对应的 Bean对象,然后调用对应的 getter 方法,并将返回结果用对应的 valueOf() 方法进行判断后再调用 toString() 方法进行输出。这是避免直接使用 print() 方法输出 null ,发生空指针异常,而附加的一个判断逻辑。

    这里有一个需要注意的点是,在从内置对象中通过属性名获取对应的 Bean对象时,是先从范围小的对象开始,小范围内的对象没有再到大的范围去找。如果小范围内有,就不会再去找了,理解这一点很重要,其实这个问题只会困扰到自己,归根结底还是要学会规范化命名,从根源上杜绝这种问题的发生。

    最后,如果不想再使用某个 Bean对象的时候,就直接使用removeAttribute(String name)方法删除掉此属性即可。

    这几个标签之前也花费了好多时间去学习,但是现在发现,学这东西根本就没卵用啊。老师真的是有毒,明明知道用不上还教,搞得自己还傻不拉几的花了这么多时间在这上面。

    相关文章

      网友评论

        本文标题:JavaBean

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