Java 杂谈善倾的知识体系构建之路

JavaBean

2018-09-01  本文已影响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 有以下几个要求:

在 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 对象,然后依次遍历表单传送过来的参数,并使用方法反射给对应的属性进行赋值。

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

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

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

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

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

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

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

上一篇下一篇

猜你喜欢

热点阅读