??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲国产精品毛片av不卡在线,国产产在线精品亚洲AAVV,亚洲AV无码一区二区三区久久精品http://www.tkk7.com/hnicypb/category/34601.html登高者必自卑Q行q者必自迩Q在q个世界上,重要的不是你正站在那里,而是你正朝什么方向移?..... zh-cnFri, 12 Sep 2008 14:56:46 GMTFri, 12 Sep 2008 14:56:46 GMT60~程l验pd-Java学习杂谈Q十一Q?-ORM http://www.tkk7.com/hnicypb/articles/228628.htmlSky YiSky YiFri, 12 Sep 2008 09:28:00 GMThttp://www.tkk7.com/hnicypb/articles/228628.htmlhttp://www.tkk7.com/hnicypb/comments/228628.htmlhttp://www.tkk7.com/hnicypb/articles/228628.html#Feedback0http://www.tkk7.com/hnicypb/comments/commentRss/228628.htmlhttp://www.tkk7.com/hnicypb/services/trackbacks/228628.htmlJava杂谈了,以ORM框架的谈论收,也算是把J2ee的最后一斚wl涵盖到了,之所以这么晚才ȝ出ORMq方面,一是笔者这两周比较忙,另一斚w也想善始善终Q仔l的先自己好好研I一下ORM框架技术,不想草率的敷衍了事?

    其实J2ee的规范指南里面就已经包括了一些对象持久化技术,例如JDOQ?a class="channel_keylink" target="_blank">Java       Data       ObjectQ就是Java对象持久化的新规范,一个用于存取某U数据仓库中的对象的标准化APIQ提供了透明的对?a class="channel_keylink" target="_blank">存储Q对开发h员来_存储数据对象完全不需要额外的代码Q如JDBC       API的用)。这些繁琐的工作已经转移到JDO产品提供商n上,使开发h员解脱出来,从而集中时间和_֊在业务逻辑上。另外,JDO很灵z,因ؓ它可以在M数据底层上运行。JDBC只是面向关系数据库(RDBMSQJDO更通用Q提供到M数据底层的存储功能,比如关系数据库、文件、XML以及对象数据库(ODBMSQ等{,使得应用可移植性更强。我们如果要理解对象持久化技术,首先要问自己一个问题:Z么传l的JDBC来持久化不再能满_家的需求了呢?

    W者认为最好是能用JDBC真正~写q程序了才能真正体会ORM的好处,同样的道理,真正拿Servlet/Jsp做过目了才能体会到Struts?Spring{框架的方便之处。很q运的是W者这两者都曄l历q,用؜q内嵌Java代码的Jsp加Servlet转发写过完整的Web目Q也?JDBC搭徏q一个完整C/S目的后台。所以现在接触到新框架才更能体会它们思想和实现的优越之处Q回从前的代码Q真是丑陋不堪啊。^_^

    回到正题Q我们来研究一下ؓ什么要从JDBC发展到ORM.单来_传统的JDBC要花大量的重复代码在初始化数据库q接上,每次增删Ҏ都要获得 Connection对象Q初始化StatementQ执行得到ResultSet再封装成自己的List或者ObjectQ这样造成了在每个数据讉KҎ中都含有大量冗余重复的代码,考虑?a class="channel_keylink" target="_blank">安全性的话,q要加上大量的事务控制和log记录。虽然我们学习了设计模式之后Q可以自己定义Factory来帮助减一部分重复的代码,但是仍然无法避免冗余的问题。其ơ,随着OO思想深入人心Q连典型的过E化语言Perl{都冠冕堂皇的加上了OO的外壻I何况?Java中繁杂的数据库访问持久化技术呢Q强调面向对象编E的l果是扑ֈ一个桥梁,使得关系型数据库存储的数据能准确的映到Java的对象上Q然后针对Java对象来设计对象和ҎQ如果我们把数据库的Table当作ClassQRecord当作Instance的话Q就可以完全用面向对象的思想来编写数据层的代码。于是乎QObject       Relationship       Mapping的概念开始普遍受到重视,管很早很早已l有人提出来了?/p>

    ~点我们已经大概清楚了,那么如何改进呢?对症下药Q首先我们要解决的是如何从Data       Schema准备完美的映到Object       SchemaQ另外要提供Ҏ据库q接对象生命周期的管理,对事务不同粒度的控制和考虑到扩展性后提供对XML、Properties{可配置化的文g的支持。到目前为止Q有很多框架和技术在试着q样做。例如似乎是装理得过了头的EJB、很早就出现目前已经不在开发和升了的Apache       OJB、首先支持Manual       SQL的iBATISQ还有公认非怼U的Hibernate{等。在分别介绍它们之前Q我q想反复q些框架都在试图做什么:

    毕竟Java Object和数据库的每一条Recordq是有很大的区别Q就是类型上来说QDB是没有Booleancd的。而Java也不得不用封装类QInteger、Double{)Z能映上数据库中为null的情况,毕竟Primitivecd是没有null值的。还有一个比较明昄问题是,数据库有主键和外键,而Java中仍然只能通过基本cd来对应字DD已Q无法规定Unique{特征,更别提外键约束、事务控制和U联操作了。另外,通过Java       Object预设某Field值去取数据库记录Q是否在q样的记录也是不能保证的。真的要设计到完全映的话,Java的Static被所有对象共享的变量怎么办?在数据库中如何表现出?#8230;…

我们能看到大量的问题像一座大山横在那些框架设计者们面前Q他们ƈ不是没有解决办法Q而是从不同的角度去考虑Q会得到很多不同的解x案,问题是应该采取哪一U呢Q甚臛_有等到真正设计出来了投入生使用了,才能印证出当初的设想是否真的能ؓ目开发带来更多的益处。笔者引用一份文档中提到一个健壮的持久化框架应该具有的特点Q?

    A       robust       persistence       layer       should       support—?/p>

    1.   Several       types       of       persistence       mechanism

    2.   Full       encapsulation       of       the       persistence       mechanism.

    3.   Multi-object       actions

    4.   Transactions       Control

    5.   Extensibility

    6.   Object       identifiers

    7.   CursorsQ?nbsp;      logical       connection       to       the       persistence       mechanism

    8.   ProxiesQ?nbsp;      commonly       used       when       the       results       of       a       query       are       to       be       displayed       in       a       list

    9.   RecordsQ?nbsp;    avoid     the     overhead       of       converting       database       records       to       objects       and       then       back       to       records

    10.   Multi       architecture

    11.   Various       database       version       and/or       vendors

    12.   Multiple       connections

    13.   Native       and       non-native       drivers

    14.   Structured       query       l

    现在来简短的介绍一下笔者用q的一些持久化框架和技术,之所以前面强调那么多共通的知识Q是希望大家不要盲从行框架Q一定要把握它的本质和卓的思想好在哪里?/p>

    1.   Apache       OJB

    OJB代表Apache       Object       Relational       BridgeQ是Apache开发的一个数据库持久型框架。它是基于J2ee规范指南下的持久型框架技术而设计开发的Q例如实CODMG       3.0规范的APIQ实CJDO规范的APIQ?nbsp;      核心实现是Persistence       Broker       API.OJB使用XML文g来实现映ƈ动态的在Metadata       layer听过一个Meta-Object-ProtocolQMOPQ来改变底层数据的行为。更高的特点包括对象缓存机制、锁理机制?Virtual       代理、事务隔L别等{。D个OJB       Mapping的简单例子ojb-repository.xmlQ?/p>

    <class-descriptor       class=“com.ant.Employee”       table=“EMPLOYEE”> <field-descriptor       name=“id”       column=“ID”

    jdbc-type=“INTEGER”       primarykey=“true”       autoincrement=“true”/>

    <field-descriptor       name=“name”       column=“NAME”       jdbc-type=“VARCHAR”/> </class-descrptor>

    <class-descriptor       class=“com.ant.Executive”       table=“EXECUTIVE”> <field-descriptor       name=“id”       column=“ID”

    jdbc-type=“INTEGER”       primarykey=“true”       autoincrement=“true”/>

    <field-descriptor       name=“department”       column=“DEPARTMENT”       jdbc-type=“VARCHAR”/>

    <reference-descriptor       name=“super”       class-ref=“com.ant.Employee”> <foreignkey       field-ref=“id”/> </reference-descriptor> </class-descrptor>

 2.   iBATIS

    iBATIS最大的特点是允许用户自己定义SQL来组配Bean的属性。因为它的SQL语句是直接写入XML文g中去的,所以可以最大程度上利用?SQL语法本n能控制的全部Ҏ,同时也能允许你用特定数据库服务?/a>的额外特性,q不局限于cMSQL92q样的标准,它最大的~点是不支持枚Dcd的持久化Q即把枚丄型的几个对象属性拼成与数据库一个字D例如VARCHAR对应的行为。这里也举一个Mapping文g的例子sqlMap.xmlQ?lt;sqlMap> <typeAlias       type=“com.ant.Test”       alias=“test”/>

    <resultMap       class=“test”       id=“result”> <result       property=“testId”       column=“TestId”/> <result       property=“name”       column=“Name”/> <result       property=“date”       column=“Date”/> </resultMap>

    <select       id=“getTestById”       resultMap=“result”       parameterClass=“int”> select       *       from       Test       where       TestId=#value# </select>

    <update       id=“updateTest”       parameterClass=“test”> Update       Tests       set       Name=#name#Q?nbsp;      Date=“date”       where       TestId=#testId# </update> </sqlMap>

    3.   Hibernate

    Hibernate无疑是应用最q泛最受欢q的持久型框Ӟ它生成的SQL语句是非怼U。虽然一度因Z能支持手工SQL而性能受到局限,但随着C?Hibernate       3.x推出Q很多缺炚w被改q,Hibernate也因此变得更加通用而时。同样先看一个Mapping文g的例子customer.hbm.xml来有一个大概印象:

    <hibernate-mapping> <class       name=“com.ant.Customer”       table=“Customers”> <id       name=“customerId”       column=“CustomerId”       type=“int”       unsaved-value=“0”> <generator       class=“sequence”> <param       name=“sequence”>   Customers_CustomerId_Seq   </param> </generator> </id>

    <property       name=“firstName”       column=“FirstName”/> <property       name=“lastName”       column=“LastName”/>

    <set       name=“addresses”       outer-join=“true”> <key       column=“Customer”/> <one-to-many       class=“com.ant.Address”/> </set>

    …

    </class>

    </hibernate-mapping>

    Hibernate有很多显著的Ҏ,最H出的就是它有自q查询语言叫做HQLQ在HQL中select       from的不是Table而是cdQ一斚w更加面向对象Q另外一斚w通过在hibernate.cfg.xml中配|Dialect为HQL可以使得整个后台与数据库q耦合Q因Z用那种数据库我都是ZHQL来查询,Hibernate框架负责帮我最l{换成特定数据库里的SQL语句。另?Hibernate在Object-Cachingq方面也做得相当Q它同时理两个U别的缓存,当数据被W一ơ取出后Q真正用的时候对象被攑֜一U缓存管理,q个时候Q何改动都会媄响到数据库;而空闲时候会把对象放在二U缓存管理,虽然q个时候与数据库字D能对应上但未绑定在一P改动不会影响到数据库的记录,主要目的是ؓ了在重复d的时候更快的拿到数据而不用再ơ请求连接对象。其实关于这U缓存的设计大家研究一?a class="channel_keylink" target="_blank">Oracle的存储机Ӟ原理是相通的Q,Oracle牺牲了空间换来时间依赖于很健壮的~存法来保证最优的企业U数据库讉K速率?/p>

    以上是一些Mapping的例子,真正在Java代码中用多半是l承各个框架中默认的Dao实现c,然后可以通过Id来查扑֯象,或者通过 Example来查找,更流行的是更具Criteria查找对象。Criteria是完全封装了SQL条g查询语法的一个工LQQ何一个查询条仉可以在Criteria中找到方法与之对应,q样可以在Java代码U别实现SQL的完全控制。另外,现在许多ORM框架的最新版本随着JDk       5.0加入AnnotationҎ都开始支持用XDoclet来自动根据Annotation来生成XML配置文g了?/p>

    W者不可能详细的讲解每一个框Ӟ也许更多的h在用HibernateQ笔者是从OJB开始接触ORM技术的Q它很原始却更容易让人理解从JDBC?ORM的过渡。更多的l节是可以从官方文档和书c中学到的,但我们应该更加看中它们设计思想的来源和闪光点,不是盲从它们的用方法?/p>

Sky Yi 2008-09-12 17:28 发表评论
]]>
~程l验pd-Java学习杂谈Q九Q?-Struts http://www.tkk7.com/hnicypb/articles/228626.htmlSky YiSky YiFri, 12 Sep 2008 09:26:00 GMThttp://www.tkk7.com/hnicypb/articles/228626.htmlhttp://www.tkk7.com/hnicypb/comments/228626.htmlhttp://www.tkk7.com/hnicypb/articles/228626.html#Feedback0http://www.tkk7.com/hnicypb/comments/commentRss/228626.htmlhttp://www.tkk7.com/hnicypb/services/trackbacks/228626.html    q期的主题是StrutsQ直译过来是支架。Struts的第一个版本是?001q?月发布的Q它提供了一个Web应用的解x案,如何让Jsp?servlet共存L供清晰的分离视图和业务应用逻辑的架构。在Struts之前Q通常的做法是在Jsp中加入业务逻辑Q或者在Servlet中生成视图{发到前台厅RStruts带着MVC的新理念当时退出几乎成Z界公认的Web应用标准Q于是当代IT市场上也出现了众多熟悉Struts的程序员。即使有新的框架再出来不用,而l用Struts的理׃加上了一条低风险Q因Z途如果开发h员变动,很容易的招进新的会Struts的IT民工啊, ^_^Q?/p>

    W者之前说的都是Struts-1Q因为新ZStruts-2Q得每ơ谈到Struts都必L明它是Struts-1q是2.W者先谈比较熟悉的 Struts-1Q下ơ再介绍一下与StrutsQ?的区别:

    1.   Struts框架整体l构

    Struts-1的核心功能是前端控制器,E序员需要关注的是后端控制器。前端控制器是是一个ServletQ在Web.xml中间配置所?Request都必ȝq前端控制器Q它的名字是ActionServletQ由框架来实现和理。所有的视图和业务逻辑隔离都是应ؓq个 ActionServletQ?nbsp;      它就像一个交通警察,所有过往的R辆必ȝq它的法|然后被送往特定的通道。所有,对它的理解就是分发器Q我们也可以叫做DispatcherQ其实了解Servlet~程的h自己也可以写一个分发器Q加上拦截request的FilterQ其实自己实C个struts框架q不是很困难。主要目的就是让~写视图的和后台逻辑的可以脱ȝ耦合Q各自同步的完成自己的工作?/p>

    那么有了ActionServlet在中间负责{发,前端的视图比如说是JspQ只需要把所有的数据SubmitQ这些数据就会到N合处理它的后端控制器ActionQ然后在里面q行处理Q处理完毕之后{发到前台的同一个或者不同的视图Jsp中间Q返回前台利用的也是Servlet里面的forward 和redirect两种方式。所以到目前为止Q一切都只是借用了Servlet的API搭徏起了一个方便的框架而已。这也是Struts最显著的特性?Q?控制器?/p>

    那么另外一个特性,可以说也是Struts-1带来的一个比较成功的理念Q就是以xml配置代替编码配|信息。以往军_Jsp往哪个servlet提交Q是要写qJsp代码中的Q也是说一旦这个提交\径要改,我们必须改写代码再重新编译。而Struts提出来的思\是,~码的只是一个逻辑名字Q它对应哪个class文g写进了xml配置文g中,q个配置文g记录着所有的映射关系Q一旦需要改变\径,改变xml文g比改变代码要Ҏ得多。这个理念可以说相当成功Q以致于后来的框枉延箋着q个思\Qxml所L作用也越来越大?/p>

    大致上来说Struts当初l我们带来的新鲜感就q么多了Q其他的所有特性都是基于方便的控制转发和可扩展的xml配置的基之上来完成它们的功能的?/p>

    下面分别介lAction和FormBeanQ?nbsp;      q两个是Struts中最核心的两个组件?br /> 2.   后端控制器Action

    Action是我们说的后端控制器,它必ȝ承自一个Action父类QStruts设计了很多种ActionQ例如DispatchAction?DynaValidationAction.它们都有一个处理业务逻辑的方法executeQ)Q传入的requestQ?nbsp;      responseQ?nbsp;      formBean和actionMapping四个对象Q返回actionForward对象。到达Action之前先会l过一?RequestProcessor来初始化配置文g的映关p,q里需要大家注意几点:

    1Q?nbsp;  Z保U程安全Q在一个应用的生命周期中,Struts框架只会为每个ActioncdZ个Action实例Q所有的客户h׃n同一个Action 实例Qƈ且所有线E可以同时执行它的executeQ)Ҏ。所以当你承父cActionQƈd了private成员变量的时候,误住这个变量可以被多个U程讉KQ它的同步必ȝE序员负责。(所有我们不推荐q样做)。在使用Action的时候,保证U程安全的重要原则是在ActioncM仅仅使用局部变量,谨慎的用实例变量。局部变量是Ҏ个线E来说私有的QexecuteҎl束p销毁,而实例变量相当于被所有线E共享?/p>

    2Q?nbsp;  当ActionServlet实例接收到Httph后,在doGetQ)或者doPostQ)Ҏ中都会调用processQ)Ҏ来处理请求?RequestProcessorcd含一个HashMapQ作为存放所有Action实例的缓存,每个Action实例在缓存中存放的属性key?Actioncd。在RequestProcessorcȝprocessActionCreateQ)Ҏ中,首先查在HashMap中是否存?Action实例。创建Action实例的代码位于同步代码块中,以保证只有一个线E创建Action实例。一旦线E创ZAction实例q把它存攑ֈ HashMap中,以后所有的U程会直接用这个缓存中的实例?/p>

    3Q?nbsp;  <action>       元素?nbsp;  <roles>   属性指定访问这个Action用户必须具备的安全角Ԍ多个角色之间逗号隔开。RequestProcessorcd预处理请求时会调用自w的 processRolesQ)ҎQ检查配|文件中是否为Action配置了安全角Ԍ如果有,p用HttpServletRequest?isUserInRoleQ)Ҏ来判断用h否具备了必要的安全性角Ԍ如果不具备,q接向客户端返回错误。(q回的视N过   <input>   属性来指定Q?/p>

    3.   数据传输对象FormBean

    Strutsq没有把模型层的业务对象直接传递到视图层,而是采用DTOQData       Transfer       ObjectQ来传输数据Q这样可以减传输数据的冗余Q提高传输效率;q有助于实现各层之间的独立,使每个层分工明确。Struts的DTO是 ActionFormQ即formBean.׃模型层应该和Web应用层保持独立。由于ActionFormcM使用了Servlet       APIQ?nbsp;      因此不提倡把ActionForm传递给模型层,       而应该在控制层把ActionForm       Bean的数据重新组装到自定义的DTO中,       再把它传递给模型层。它只有两个scopeQ分别是session和request.Q默认是sessionQ一个ActionForm标准的生命周期是Q?Q?nbsp;  控制器收到请?nbsp;      -> 2Q?nbsp;  从request或session中取出ActionForm实例Q如不存在就创徏一?nbsp;      -> 3Q?nbsp;  调用ActionForm的resetQ)Ҏ       -> 4Q?nbsp;  把实例放入session或者request?nbsp;      -> 5Q?nbsp;  用戯入表达数据组装到ActionForm?nbsp;      -> 6Q?nbsp;  如眼张方法配|了p用validateQ)Ҏ           -> 7Q?nbsp;  如验证错误就转发l?nbsp;  <input>   属性指定的地方Q否则调用executeQ)Ҏ

    validateQ)Ҏ调用必须满两个条gQ?Q?nbsp;  ActionForm       配置了Action映射而且name属性匹?Q?nbsp;  <aciton>       元素的validate属性ؓtrue

    如果ActionForm在request范围内,那么对于每个新的h都会创徏新的ActionForm实例Q属性被初始化ؓ默认|那么reset Q)Ҏ显得没有必要;但如果ActionForm在session范围内,同一个ActionForm实例会被多个h׃nQresetQ)Ҏ在这U情况下极ؓ有用?/p> 4.   验证框架和国际化

    Struts有许多自qҎ,但是基本上大家还是不太常用,说白了它们也是基于JDK中间的很?a class="channel_keylink" target="_blank">Java基础包来完成工作。例如国际化、验证框架、插件自扩展功能、与其他框架的集成、因为各大框架基本都有提供这LҎ,Struts也ƈ不是做得最好的一个,q里也不惛_说。Struts的验证框Ӟ是通过一个validator.xml的配|文件读入验证规则,然后在validation-rules.xml里面扑ֈ验证实现通过自动为Jsp插入 Javascript来实玎ͼ可以说做得相当简陋。弹出来的JavaScript框不但难看还很多冗余信息Q笔者宁愿用formBean验证或?Action的saveErrorsQ)Q验证逻辑虽然要自己写Q但面隐藏/现的警告提C更加h性化和美观一些?/p>

    至于Struts的国际化Q其实无论哪个框架的国际化,java.util.LocalecL最重要的Java       I18NcR在Java语言中,几乎所有的对国际化和本地化的支持都依赖于这个类。如果Javacd中的某个cdq行的时候需要根据Locale对象来调整其功能Q那么就U这个类是本地敏感的QLocale-SensitiveQ,       例如java.text.DateFormatcd是,依赖于特定Locale.

    创徏Locale对象的时候,需要明的指定其语a和国家的代码Q语a代码遵从的是ISO-639规范Q国家代码遵从ISO-3166规范Q可以从http://www.unicode.org/unicode/onlinedat/languages.html http://www.unicode.org/unicode/onlinedat/countries.htm

    Struts的国际化是基于properties的message/key对应来实现的Q笔者曾写过一个程序,所有Jsp面上没有Q何Text文本Ԍ全部都用的是   <beanQmessage>   去Properties文g里面读,q个时候其实只要指定不同的语言区域M同的Properties文g实C国际化。需要注意的是不同语a的字W写qProperties文g的时候需要{化成Unicode码,JDK已经带有转换的功能。JDK的bin目录中有native2asciiq个命oQ可以完成对*.txt?.properties的Unicode码{换?/p>

Sky Yi 2008-09-12 17:26 发表评论
]]>
~程l验pd-Java学习杂谈Q十Q?-Spring http://www.tkk7.com/hnicypb/articles/228627.htmlSky YiSky YiFri, 12 Sep 2008 09:26:00 GMThttp://www.tkk7.com/hnicypb/articles/228627.htmlhttp://www.tkk7.com/hnicypb/comments/228627.htmlhttp://www.tkk7.com/hnicypb/articles/228627.html#Feedback0http://www.tkk7.com/hnicypb/comments/commentRss/228627.htmlhttp://www.tkk7.com/hnicypb/services/trackbacks/228627.html    引用《Spring2.0技术手册》上的一D话Q?/p>

    Spring的核心是个轻量容器Q它是实现IoC容器和非侵入性的框架Qƈ提供AOP概念的实现方式;提供Ҏ久层、事务的支持Q提供MVC       Web框架的实玎ͼq对于一些常用的企业服务API提供一致的模型装Q是一个全方位的应用程序框Ӟ除此之外Q对于现存的各种框架QSpring也提供了与它们相整合的方案?/p>

    接下来笔者先谈谈自己的一些理解吧QSpring框架的发赯之前一本很著名的书名字大概是《J2ee       Development       without       EJB》,他提倡用轻量U的lg代替重量U的EJB.W者还没有看完那本著作Q只阅读了部分章节。其中有一点分析觉得是很有道理的:

    EJB里在服务?/a>端有Web       Container和EJB       ContainerQ从前的观点是各层之间应该在物理上隔,Web       Container处理视图功能、在EJB       Container中处理业务逻辑功能、然后也是EBJ       Container控制数据库持久化。这L层次是很清晰Q但是一个很严重的问题是Web       Container和EJB       Container毕竟是两个不同的容器Q它们之间要通信得用的是RMI机制和JNDI服务Q同样都在服务端Q却物理上隔,而且每次业务h都要q程调用Q有没有必要呢?看来q隔离都是好的?/p>

    再看看轻量和重量的区别,W者看q很多种说法Q觉得最有道理的是轻量代表是POJO       +       IoCQ重量的代表是Container       +       Factory.QEJB2.0是典型的重量U组件的技术)我们量使用轻量U的Pojo很好理解Q意义就在于兼容性和可适应性,UL不需要改变原来的代码。而Ioc与Factory比v来,Ioc的优Ҏ更大的灵zL,通过配置可以控制很多注入的细节,而Factory模式Q行为是相对比较闭固定的,生一个对象就必须接受它全部的特点Q不是否需要。其实轻量和重量都是相对的概念,使用资源更少、运行负载更的自然q轻量?/p>

    话题扯远了,因ؓSpring框架带来了太多可以探讨的地方。比如它的非侵入性:指的是它提供的框架实现可以让E序员编E却感觉不到框架的存在,q样所写的代码q没有和框架l定在一P可以随时抽离出来Q这也是Spring设计的目标。Spring是唯一可以做到真正的针Ҏ口编E,处处都是接口Q不依赖l定M实现cR同ӞSpringq设计了自己的事务管理、对象管理和Model2       的MVC框架Q还装了其他J2ee的服务在里面Q在实现上基本都在用依赖注入和AOP的思想。由此我们大概可以看到Spring是一个什么概念上的框Ӟ代表了很多优U思想Q值得深入学习。笔者强调,学习q不是框Ӟ而是框架代表的思想Q就像我们当初学Struts一?#8230;…

    1.Spring       MVC

    关于IoC和AOPW者在上篇已经E微解释q了Q这里先通过Spring的MVC框架来给大家探讨一下Spring的特点吧。(毕竟大部分h已经很熟悉Struts了,Ҏ一下吧Q?/p>

    众所周知MVC的核心是控制器。类似Struts中的ActionServletQSpring里面前端控制器叫做DispatcherServlet.里面充当Action的组件叫做ControllerQ返回的视图层对象叫做ModelAndViewQ提交和q回都可能要l过qo的组件叫?Interceptor.

    让我们看看一个从h到返回的程吧:

    Q?Q?nbsp;  前台Jsp或Html通过点击submitQ将数据装入了request?/p>

    Q?Q?nbsp;  h被Interceptor拦截下来Q执行preHandlerQ)Ҏ出前|判?/p>

    Q?Q?nbsp;  h到达DispathcerServlet

    Q?Q?nbsp;  DispathcerServlet通过Handler       Mapping来决定每个reuqest应该转发l哪个后端控制器Controlle



Sky Yi 2008-09-12 17:26 发表评论
]]>
~程l验pd-Java学习杂谈Q九Q?-Struts2 http://www.tkk7.com/hnicypb/articles/228625.htmlSky YiSky YiFri, 12 Sep 2008 09:24:00 GMThttp://www.tkk7.com/hnicypb/articles/228625.htmlhttp://www.tkk7.com/hnicypb/comments/228625.htmlhttp://www.tkk7.com/hnicypb/articles/228625.html#Feedback0http://www.tkk7.com/hnicypb/comments/commentRss/228625.htmlhttp://www.tkk7.com/hnicypb/services/trackbacks/228625.htmlJava       Virtual       Machine的研IӞ׃实习分配到项目组里面Q不想从前那么闲了,好不Ҏ才抽出时间来l箋q个话题的帖子。我打算把J2ee的部分结束之后,再谈?JVM?a class="channel_keylink" target="_blank">JavaScriptQ只要笔者有最新的学习W记ȝ出来Q一定会拿来及时和大家分享的。衷心希望与热爱Java的关大同仁共同进?#8230;…

    q次准备l箋上次的话题先讲讲Struts-2Q手下简短回一D历Ԍ随着旉的推U,Web应用框架l常变化的需求,产生了几个下一?nbsp;      Struts的解x案。其中的Struts       Ti       l箋坚持       MVC模式的基上改q,l箋Struts的成功经验?nbsp;      WebWork目是在2002q?月发布的Q它对Struts式框架进行了革命性改q,引进了不新的思想Q概念和功能Q但和原Struts代码q不?nbsp;      宏VWebWork是一个成熟的框架Q经q了好几ơ重大的改进与发布。在2005q?2月,WebWork与Struts       Ti军_合拼Q?nbsp;      再此同时Q?nbsp;      Struts       Ti       改名?nbsp;      Struts       Action       Framework       2.0Q成为Struts真正的下一代?/p>

    看看Struts-2的处理流E:

    1Q?nbsp;  Browser产生一个请求ƈ提交框架来处理:Ҏ配置军_使用哪些拦截器、actioncdl果{?/p>

    2Q?nbsp;  hl过一pd拦截器:Ҏh的别不同拦截器做不同的处理。这和Struts-1的RequestProcessorcd怼?/p>

    3Q?nbsp;  调用ActionQ?nbsp;      产生一个新的action实例Q调用业务逻辑Ҏ?/p>

    4Q?nbsp;  调用产生l果Q匹配result       classq调用生实例?/p>

    5Q?nbsp;  h再次l过一pd拦截器返回:q程也可配置减少拦截器数?/p>

    6Q?nbsp;  hq回用户Q从controlq回servletQ生成Html.

    q里很明昄一Ҏ不存在FormBean的作用域装Q直接可以从Action中取得数据?nbsp;      q里有一个Strut-2配置的web.xml文gQ?/p>

    <filter>

    <filter-name>   controller   </filter-name>

    <filter-class>   org.apache.struts.action2.dispatcher.FilterDispatcher   </filter-class>

    </filter>

    <filter-mapping>

    <filter-name>   cotroller   </filter-name>

    <url-pattern>   /*   </url-pattern>

    </filter-mapping>

    注意C往的servlet变成了filterQActionServlet变成了FilterDispatcherQ?.do变成?*.filter 配置定义了名Uͼ供关联)和filter的类。filter       mapping让URI匚w成功的的h调用该filter.默认情况下,扩展名ؓ   ".action   ".q个是在default.properties文g里的   "struts.action.extension   "属性定义的?/p>

    default.properties是属性定义文Ӟ通过在项目classpath路径中包含一个名?#8220;struts.properties”的文件来讄不同的属性倹{而Struts-2的默认配|文件名为struts.xml.׃1?的action扩展名分别ؓ。do和。actionQ所以很方便能共存。我们再来看一个Struts-2的action代码Q?/p>

    public   class   MyAction   {

    public   String   executeQ)   throws   Exception   {

    //do   the   work return   "success   "Q?/p>

    }

    }
   很明昄区别是不用再l承Mcd接口Q返回的只是一个StringQ无参数。实际上在Struts-2中Q何返回String的无参数Ҏ都可以通过配置来调用action.所有的参数从哪里来获得呢?{案是Inversion       of       Control技术(控制反{Q。笔者尽量以最通俗的方式来解释Q我们先试图让这个Action获得reuqest对象Q这样可以提取页面提交的M参数。那么我们把request设ؓ一个成员变量,然后需要一个对它的setҎ。由于大部分的action都需要这么做Q我们把q个setҎ作ؓ接口来实现?

    public   interface   ServletRequestAware   {

    public   void   setServletRequestQHttpServletRequest   requestQ;

    }

    public   class   MyAction   implements   ServletRequestAware   {

    private   HttpServletRequest   requestQ?/p>

    public   void   setServletRequestQHttpServletRequest   requestQ?nbsp;  {

    this.request   =   requestQ?/p>

    }

    public   String   executeQ)   throws   Exception       {

    //     do   the   work   directly   using   the   request

    return       Action.SUCCESSQ?/p>

    }

    }

    那么谁来调用q个setҎ呢?也就是说谁来控制q个action的行为,以往我们都是自己在适当的地方写上一?action.setServletRequestQ?#8230;Q,也就是控制权在程序员q边。然而控制反转的思想是在哪里调用交给正在q行的容器来军_Q只要利用Java反射机制来获得Method对象然后调用它的invokeҎ传入参数p做到Q这h制权׃E序员这边{Ud了容器那辏V程序员可以减轻很多J琐的工作更多的x业务逻辑。Request可以q样注入到action中,其他M对象也都可以。ؓ了保证action的成员变量线E?a class="channel_keylink" target="_blank">安全Q?Struts-2的action不是单例的,每一个新的请求都会生一个新的action实例?/p>

    那么有h会问Q到底谁来做q个对象的注入工作呢Q答案就是拦截器。拦截器又是什么东西?W者再来尽量通俗的解释拦截器的概c大家要理解拦截器的话,首先一定要理解GOF23U设计模式中的Proxy模式?/p>

    A对象要调用fQ)Q它希望代理lB来做Q那么Bp获得A对象的引用,然后在B的fQ)中通过A对象引用调用A对象的fQ)ҎQ最l达到A的fQ)被调用的目的。有没有Z觉得q样很麻烦,Z么明明只要A.fQ)可以完成的一定要装到B的fQ)Ҏ中去Q有哪些好处呢?

    1Q?nbsp;  q里我们只有一个AQ当我们有很多个A的时候,只需要监视B一个对象的fQ)Ҏ可以从全局上控制所有被调用的fQ)Ҏ?/p>

    2Q?nbsp;  另外Q既然代理hB能获得A对象的引用,那么B可以军_在真正调A对象的fQ)Ҏ之前可以做哪些前|工作,调完q回前可有做哪些后置工作?/p>

    讲到q里Q大家看出来一Ҏ截器的概念了么?它拦截下一调fQ)Ҏ的请求,然后l一的做处理Q处理每个的方式q可以不同,解析A对象可以L别)Q处理完毕再放行。这样像不像Ҏ动的x横切了一刀Q对所有想通过的水分子q行搜nQ然后再放行Q这也就是AOPQAspect       of       Programming面向切面~程Q的思想?/p>

    AnywayQStruts-2只是利用了AOP和IoC技术来减轻action和框架的耦合关系Q力囑ֈ最大程度重用action的目的。在q样的技术促动下QStruts-2的action成了一个简单被框架使用的POJOQPlain       Old       Java       ObjectQŞ了。实事上AOP和IoC的思想已经遍布新出来的每一个框架上Q他们ƈ不是多么新的技术,利用的也都是JDK早已可以最到的事情Q它们代表的是更加面向接口编E,提高重用Q增加扩展性的一U思想。Struts-2只是部分的用这两种思想来设计完成的Q另外一个最q很火的框架 SpringQ更大程度上代表了这两种设计思想Q笔者将于下一来q一步探讨Spring的结构?/p>

Sky Yi 2008-09-12 17:24 发表评论
]]>
~程l验pd-Java学习杂谈Q七Q?/title><link>http://www.tkk7.com/hnicypb/articles/228623.html</link><dc:creator>Sky Yi</dc:creator><author>Sky Yi</author><pubDate>Fri, 12 Sep 2008 09:21:00 GMT</pubDate><guid>http://www.tkk7.com/hnicypb/articles/228623.html</guid><wfw:comment>http://www.tkk7.com/hnicypb/comments/228623.html</wfw:comment><comments>http://www.tkk7.com/hnicypb/articles/228623.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/hnicypb/comments/commentRss/228623.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/hnicypb/services/trackbacks/228623.html</trackback:ping><description><![CDATA[ l于又静下来l箋写这个主题的l篇Q前六篇主要讲了一些J2se斚w的经验和感受Q?g<a class="channel_keylink" target="_blank">Java</a>应用范围已经被J2ee占据了相当大的一块领域,有些人甚臛_U?a class="channel_keylink" target="_blank">Java</a>被J2ee所取代了。不知道大家如何来理解所谓的J2ee QJava2       Enterprise       EditionQ,也就是Java企业U应用? <p>    W者的观点是,技术的发展是顺应世界变化的势的,从C/Sq渡到B/S模式Q从客户端的角度考虑企业U应用或者说电子商务领域不在兛_客户端维护问题,q个d已经交给了Q何一台PC都会有的览器去l护Q从<a class="channel_keylink" target="_blank">服务?/a>端的角度考虑Q以往C/S中的TCP/IP<a class="channel_keylink" target="_blank">协议</a>实现载体ServerSocket被Web       Server       Container所取代Q例如大安很熟悉的Tomcat、JBoss、WebLogic{等。M一切的转变都是Z使得Java技术能更好的ؓ人类生生活所服务?/p> <p>    有h会问Q直接去学J2ee跌J2se行否Q笔者是肯定不赞成的Q实际上实有h走这条\Q但W者自w体会是正是׃J2se的基很牢固,才会D在J2ee学习的道路上风水Q知识点上不会有什么迷惑的地方。D个简单的例子吧:</p> <p>    W者曾l跟大学同学讨论下面q两U写法的区别Q?/p> <p>    ArrayList       list       =       new       ArrayListQ)Q?nbsp;                //W者不说反对,但至不赞成</p> <p>    List       list       =       new       ArrayListQ)Q?nbsp;                          //W者支?/p> <p>    曄W者跟同学争论了几个小Ӟ他非说第一U写法更U学Q第二种完全没有必要。我无法完全说服他,但笔者认好的习惯和意识是M时候都应该针对接口~程Q以辑ֈ解耦合和可扩展性的目的。下面就以接口开始进入J2ee的世界吧Q?/p> <p>    <strong>1.   J2ee与接?/strong></p> <p>    每一个版本的J2ee都对应着一个确定版本的JDKQJ2ee1.4对应Jdk1.4Q现在比较新的是JDK5.0Q自然也会有J2EE       5.0.其实W者一直在用的是J2EE1.4Q不q没什么关p,大家可以下Q何一个版本的J2ee       api来稍微浏览一下。笔者想先声明一个概念,J2ee也是源自JavaQ所以底层的操作依然调用到很多J2se的库Q所以才大家先牢牢掌握J2se 的主技术?/p> <p>    J2ee       api有一个特点,大家比较熟悉的几个包java.jms、javax.servlet.http、javax.ejb{都以interface居多Q实现类较少。其实大家真正在用的时候百分之六十以上都在反复的查着javax.servlet.httpq个包下面几个实现类的api函数Q其他的包很问z。笔者徏议在学习一U技术之前,Ҏ体的框架有一个了解是很有必要的,J2ee旨在通过interface的声明来规范实现的行为,MW三方的厂商惌提供自己品牌的实现前提也是遵循这些接口定义的规则。如果在从前J2se学习的道路上Ҏ口的理解很好的话Q这里的体会是非常深刻的,举个单的例子Q?/p> <p>    public       interface       Mp3{ </p> <p>    public       void       playQ)Q?/p> <p>    public       void       recordQ)Q?/p> <p>    public       void       stopQ)Q}</p> <p>    如果我定义这个简单的接口Q发布出去,规定MW三方的公司xq名字为Mp3的品都必须实现q个接口Q也是臛_提供接口中方法的具体实现。这个意义已l远q不止是面向对象的多态了Q只有厂商遵循J2ee的接口定义,世界上的J2eeE序员才能针对统一的接口进行程序设计,最l不用改变代码只是因Z用了不同厂商的实现类而有不同的特性Ş了,本质上说Q无论哪一U厂商实现都完成了职责范围内的工作。这个就是笔者想一直强调的Q针Ҏ口编E的思想?/p> <p>    接口到底有什么好处呢Q我们这栯惻I现在有AppleMp3、SonyMp3、SamsungMp3都实Cq个Mp3的接口,于是都有了play?record、stopq三个功能。我们将Mp3产品座位一个组件的时候就不需要知道它的具体实玎ͼ只要看到接口定义知道q个对象?个功能就可以使用了。那么类g面这L业务完全可以在M旉?个品牌扩展到L个品牌,开个玩W的_目l理高高在上的写?0个接口里的方法声明,然后׃l手下的E序员去写里面的l节Q由于接口已l统一Q即每个Ҏ传入和传出的格式已经l一Q,l理只需x全局的业务就可以天天端杯咖啡走来走去了:</p> <p>    public       Mp3       createQ)Q?/p> <p>    public       void       copyQMp3       mp3Q;</p> <p>    public       Mp3       getMp3Q)Q?/p> <p>    最后用一个简单的例子说明接口Q一?L池的手电{,可以装入M牌子?L池,只要它符?L池的规范Q装入之后Q何看不到是什么牌子,只能感受到手늭在完成它的功能。那么生产手늭的厂商和生5L池的厂商可以完全解除依赖关p,可以各自自由开发自q产品Q因为它们都遵守5L池应有的形状、正负极位置{约定。这下大家能Ҏ口多一点体会了么?</p>  <strong>2.   lg和容?/strong> <p>    针对接口是笔者特意强调的J2ee学习之\必备的思想Q另外一个就是比较常规的lg和容器的概念了。很多教材和专业|站都说J2EE的核心是一l规范与指南Q强调J2ee的核心概念就是组?容器Q这实是无可厚非的。随着来多的J2ee框架出现Q相应的每种框架都一般有与之对应的容器?/p> <p>    容器Q是用来理lg行ؓ的一个集合工Plg的行为包括与外部环境的交互、组件的生命周期、组件之间的合作依赖关系{等。J2ee包含的容器种cdU有 Web容器、Application       Client容器、EJB容器、Applet客户端容器等。但在笔者看来,现在容器的概念变得有Ҏp了Q大家耳熟能详是那些功能强大的开源框Ӟ比如 Hibernate、Struts2、Spring、JSF{,其中Hibernate基于JDBC的基装了对事务和会话的理Q大大方便了Ҏ据库操作的繁琐代码,从这个意义上来说它已l接q容器的概念了,EJB的实体Bean也逐渐被以HibernateZ表的持久化框架所取代?/p> <p>    lgQ本意是指可以重用的代码单元Q一般代表着一个或者一l可以独立出来的功能模块Q在J2ee中组件的U类有很多种Q比较常见的是EJBlg、DAOlg、客Llg或者应用程序组件等Q它们有个共同特Ҏ分别会打包成。warQ。jarQ。jarQ。earQ每个组件由特定格式的xml描述W文件进行描qͼ而且<a class="channel_keylink" target="_blank">服务?/a>端的lg都需要被部v到应用服务器上面才能够被使用?/p> <p>    E微理解完组件和容器Q还有一个重要的概念是分层模型Q最著名的当然是MVC三层模型。在一个大的工E或目中,Z让前台和后台各个模块的编Eh员能够同时进行工作提高开发效率,最重要的就是实现层与层之间的耦合关系Q许多分层模型的宗旨和开源框架所q求的也是q样的效果。在W者看来,一个完整的 Web目大概有以下几个层ơ:</p> <p>    aQ?nbsp;  表示层(Jsp、Html、Javascript、Ajax、Flash{等技术对其支持)</p> <p>    bQ?nbsp;  控制层(Struts、JSF、WebWork{等框架在基于Servlet的基上支持,负责把具体的h数据Q有时卸载重新装载)导向适合处理它的模型层对象)</p> <p>    cQ?nbsp;  模型层(W者认为目前最好的框架是SpringQ实质就是处理表C层l由控制层{发过来的数据Q包含着大量的业务逻辑Q?/p> <p>    dQ?nbsp;  数据层(Hibernate、JDBC、EJB{,由模型层处理完了持久化到数据库中Q?/p> <p>    当然Q这仅仅是笔者个人的观点Q仅仅是供大家学习做一个参考,如果要实现这些层之间的完全分,那么一个大的工E,可以仅仅通过增加人手来完成d。虽然《h月神话》中已经很明的阐述了增加h手ƈ不能是效率增加,很大E度上是因ؓ彼此做的工作有顺序上的依赖关pL者说隑ֺ和工作量上的巨大差距。当然理想状态在真实世界中是不可能达到的Q但我们永远应该朝着q个方向M断努力。最开始所提倡的针对接口来编E,哪怕是小的细节,写一条List       list=       =       new       ArrayListQ)语句也能体现着处处皆用接口的思想在里面。AnywayQ这只是个开,W者会pqq的J2ee技术和框架再细化谈一些经?/p> <img src ="http://www.tkk7.com/hnicypb/aggbug/228623.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/hnicypb/" target="_blank">Sky Yi</a> 2008-09-12 17:21 <a href="http://www.tkk7.com/hnicypb/articles/228623.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>~程l验pd-Java学习杂谈Q八Q?/title><link>http://www.tkk7.com/hnicypb/articles/228624.html</link><dc:creator>Sky Yi</dc:creator><author>Sky Yi</author><pubDate>Fri, 12 Sep 2008 09:21:00 GMT</pubDate><guid>http://www.tkk7.com/hnicypb/articles/228624.html</guid><wfw:comment>http://www.tkk7.com/hnicypb/comments/228624.html</wfw:comment><comments>http://www.tkk7.com/hnicypb/articles/228624.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/hnicypb/comments/commentRss/228624.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/hnicypb/services/trackbacks/228624.html</trackback:ping><description><![CDATA[l于正式q入J2ee的细节部分了Q首当其冲的当然是Servlet和Jsp了,上篇曄提到qJ2ee只是一个规范和指南Q定义了一l必要遵@的接口,核心概念是组件和容器。曾l有的h问笔者Servlet的Class文g是哪里来的?他认为是J2ee官方提供的,我D了一个简单的反例Q稍微检查了一下Tomcat5.0里面的Servlet.jar文g和JBoss里面的Servlet.jar文g大小Q很明显是不一LQ至已l说明了它们不是源自同根的吧。其实Servlet是由容器ҎJ2ee的接口定义自己来实现的,实现的方式当然可以不同,只要都遵守J2ee规范和指南? <p>    上述只是一个常见的误区|了Q告诉我们要~译q行ServletQ是要依赖于实现它的容器的,不然qjar文g都没有,~译都无法进行。那么Jsp呢? <a class="channel_keylink" target="_blank">Java</a>       Server       Page的简Uͼ是ؓ了开发动态网而诞生的技术,其本质也是JspQ在~写完毕之后会在容器启动时经q编译成对应的Servlet.只是我们利用Jsp 的很多新Ҏ,可以更加专注于前后台的分,早期Jsp做前台是满流行的Q毕竟里面支持Html代码Q这让前台美工h员可以更有效率的d成自q工作。然后Jsp请求{发到后台的ServletQ由Servlet处理业务逻辑Q再转发回另外一个Jsp在前台显C出来。这g已经成ؓ一U常用的模式Q最初笔者学习J2ee的时候,大量旉也在~写q样的代码?/p> <p>    管现在做前台的技术越来越多,例如Flash、Ajax{,已经有很多h不再认ؓJsp重要了。笔者觉得Jsp带来的不仅仅是前后端分离的设计理念,它的另外一Ҏ术成׃我们今天用的很多框架Q那是Tag标签技术。所以与其说是在学习JspQ不如更清醒的告诉自己在不断的理解Tag标签的意义和本质?/p> <p>    <strong>1.   Servlet以及Jsp的生命周?/strong></p> <p>    Servlet是Jsp的实质,管容器对它们的处理有所区别。Servlet有initQ)Ҏ初始化,serviceQ)Ҏq行Web服务Q?destroyQ)Ҏq行销毁,从生到灭都由容器来掌握,所以这些方法除非你惌己来实现ServletQ否则是很少会接触到的。正是由于很接触,才容易被q大初学者所忽略Q希望大家至记住Servlet生命周期Ҏ都是回调Ҏ。回调这个概늮单来说就是把自己注入另外一个类中,由它来调用你的方法,所谓的另外一个类是Web容器Q它只认识接口和接口的方法,注入q来的是怎样的对象不,它只会根据所需调用q个对象在接口定义存在的那些Ҏ。由容器来调用的Servlet对象的初始化、服务和销毁方法,所以叫做回调。这个概念对学习其他J2ee技术相当关键!</p> <p>    那么Jsp呢?本事上是ServletQ还是有些区别的Q它的生命周期是q样的:</p> <p>    aQ?nbsp;  一个客L的Request到达<a class="channel_keylink" target="_blank">服务?/a>       -> </p> <p>    bQ?nbsp;  判断是否W一ơ调?nbsp;      ->       是的话编译Jsp成Servlet </p> <p>    cQ?nbsp;  否的话再判断此Jsp是否有改?nbsp;      ->       是的话也重新~译Jsp成Servlet </p> <p>    dQ?nbsp;  已经~译最q版本的Servlet装蝲所需的其他Class eQ?nbsp;  发布ServletQ即调用它的ServiceQ)Ҏ</p> <p>    所以JspL的是W一ơLoad~慢Q以后都会很快的q行。从它的生命的周期确实不隄出来q个特点Q客L的操作很会改变Jsp的源码,所以它不需要编译第二次׃直可以ؓ客户端提供服务。这里稍微解释一下Http的无状态性,因ؓ发现很多解,Http的无状态性是指每ơ一张页面显C出来了Q与<a class="channel_keylink" target="_blank">服务?/a>的连接其实就已经断开了,当再ơ有提交动作的时候,才会再次与服务器q行q接h提供服务。当然还有现在比较流行的是Ajax与服务器异步通过 xml交互的技术,在做前台的领域潜力巨大,W者不是Ajax的高手,q里无法为大家解释?strong>2.   Tag标签的本?/strong> </p> <p>    W者之前说了,Jsp本n初衷是得Web应用前后台的开发可以脱耦合分开有效的进行,可惜q个理念的A献反倒不如它带来的Tag技术对J2ee的A献要大。也许已l有很多人开始用Tag技术了却ƈ不了解它。所以才大家在学习J2ee开始的时候一定要认真学习JspQ其实最重要的就是明白标{本质?/p> <p>    Html标签我们都很熟悉了,?nbsp;  <html>   ?nbsp;  <head>   ?nbsp;  <body>   ?nbsp;  <title>   QJsp带来的Tag标签遵@同样的格式,或者说更严格的Xml格式规范Q例?nbsp;  <jspQinclude>   ?nbsp;  <jspQuseBean>   ?nbsp;  <cQif>   ?nbsp;  <cQforEach>   {等。它们没有什么神U的地方Q就其源头也q是<a class="channel_keylink" target="_blank">Java</a>       Class而已QTag标签的实质也是一DJava代码Q或者说一个Class文g。当配置文g讄好去哪里Lq些Class的\径后Q容器负责将面中存在的标签对应到相应的Class上,执行那段特定的Java代码Q如此而已?/p> <p>    说得明白一点的话还是D几个单的例子说明一下吧Q?/p> <p>    <jspQinclude>   d里找执行什么class呢?首先q是个jspcd的标{,当然要去jspcdL相应的class了,同样它也是由Web容器来提供,例如 Tomcat应该去安装目录的lib文g夹下面的jsp-api.jar里面找,有兴的可以L一扑֕Q?/p> <p>    <cQforEach>   又去哪里扑֑Q这个是由Jsp2.0版本推荐的和核心标记库的内容Q例?nbsp;  <cQif>   对应在面中做if判断的功能的一断Java代码。它的class文g在jstl.jarq个cd里面Q往往q需要和一个standard.jarcd一起导入,攑֜具体Web目的WEB-INF的lib目录下面可以用了?/p> <p>    Z|唆一句,Web       Project的目录结构是相对固定的,因ؓ容器会按照固定的路径d扑֮需要的配置文g和资源,q个M一本J2ee入门书上都有Q这里就不介l了。了解Tag的本质还要了解它的工作原理,所以大家去J2ee的API里找到ƈ研究q个包:javax.servlet.jsp.tagext.它有一些接口,和一些实现类Q专门用语开发TagQ只有自׃自写出几个不同功能的标签Q才是真正理解了标{原理。别忘记了自己开发的标签要自己去完成配置文gQ容器只是集成了d里寻找jsp标签对应class的\径,自己写的标签库当然要告诉容器d里找啦?/p> <p>    说了q么多,我们Z么要用标{֑Q完全在Jsp里面来个   <%       %>   可以在里面L写Java代码了,但是长期实践发现面代码l一都是与html同风格的标记语言更加有助于美工h员进行开发前収ͼ它不需要懂JavaQ只要JavaE序员给个列表告诉美工什么标{֏以完成什么逻辑功能Q他可以专注于工Q也是q一步隔M前后台的工作吧!</p> <p>    3.   成就Web框架框架是什么?曄看过q样的定义:与模式类|框架也是解决特定问题的可重用ҎQ框架是一个描q性的构徏块和服务集合Q开发h员可以用来达成某个目标。一般来_框架提供了解xc问题的基础设施Q是用来创徏解决Ҏ的工P而不是问题的解决Ҏ?/p> <p>    正是׃Tag的出玎ͼ成就了以后出现的那么多Web框架Q它们都开发了自己成熟实用的一套标{,然后q定的Xml文g来配|加载信息,力图使得Web 应用的开发变得更加高效。下面这些标{应对很多人来说相当熟悉了Q?/p> <p>    <htmlQpassword> </p> <p>    <logicQequal> </p> <p>    <beanQwrite> </p> <p>    <fQview> </p> <p>    <hQform> </p> <p>    <hQmessage></p> <p>    它们分别来自Struts和JSF框架Q最强大的功能在于控制{发,是MVC三层模型中间完成控制器的工作。Struts-1实际上ƈ未做到真正的三层隔离Q这一点在Struts-2上得C很大的改q。而Jsf向来以比较完善合理的标签库受Ch们推崇?/p> <p>    今天大概讲q么多吧Q再ơ需要强调的是Servlet/Jsp是学习J2ee必经之\Q也是最基础的知识,希望大家l与_的重视!</p> <img src ="http://www.tkk7.com/hnicypb/aggbug/228624.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/hnicypb/" target="_blank">Sky Yi</a> 2008-09-12 17:21 <a href="http://www.tkk7.com/hnicypb/articles/228624.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>~程l验pd-Java学习杂谈Q六Q?http://www.tkk7.com/hnicypb/articles/228622.htmlSky YiSky YiFri, 12 Sep 2008 09:20:00 GMThttp://www.tkk7.com/hnicypb/articles/228622.htmlhttp://www.tkk7.com/hnicypb/comments/228622.htmlhttp://www.tkk7.com/hnicypb/articles/228622.html#Feedback0http://www.tkk7.com/hnicypb/comments/commentRss/228622.htmlhttp://www.tkk7.com/hnicypb/services/trackbacks/228622.htmlJava杂谈的J2se部分。最后这打谈一?a class="channel_keylink" target="_blank">Java中的RMI机制和JVM沙箱安全框架?

    1.   Java中的RMI机制

    RMI的全U是q程Ҏ调用Q相信不朋友都听说q,基本的思\可以用一个经典比Ҏ解释QA计算机想要计一个两个数的加法,但A自己做不了,于是叫另外一台计机B帮忙QB有计加法的功能QA调用它就像调用这个功能是自己的一hѝ这个就叫做q程Ҏ调用了?/p>

    q程Ҏ调用是EJB实现的支柱,建立分布式应用的核心思想。这个很好理解,再拿上面的计加法例子,A只知道去call计算机B的方法,自己q没有B的那些功能,所以A计算机端无法看到B执行q段功能的过E和代码Q因为看都看不到Q所以既没有ZH取也没有机会去改动Ҏ代码。EJB正式Zq样的思想来完成它的Q务的。当单的加法变成复杂的数据库操作和电子商务交易应用的时候,q样?a class="channel_keylink" target="_blank">安全性和分布式应用的便利性就表现出来优势了?/p>

    好了Q回到细节上Q要如何实现q程Ҏ调用呢?我希望大家学习Q何技术的时候可以试着依赖自己的下意识判断Q只要你的想法是合理健壮的,那么很可能实际上它就是这么做的,毕竟真理都蕴藏在q_的生zȝ节中。这样只要带着一些薄qJava基础来思考RMIQ其实也可以惛_个大概来?/p>

    aQ?nbsp;  需要有一?a class="channel_keylink" target="_blank">服务?/a>角色Q它拥有真正的功能代码方法。例如BQ它提供加法服务bQ?nbsp;  如果惌E用B的功能,需要知道B的IP地址cQ?nbsp;  如果惌E用B的功能,q需要知道B中那个特定服务的名字

    我们很自然可以想到这些,虽然不完善,但已l很接近正确的做法了。实际上RMI要得以实现还得意于Java一个很重要的特性,是Java反射机制。我们需要知道服务的名字Q但又必隐藏实现的代码Q如何去做呢Q答案就是:接口Q?/p>

    举个例子Qpublic   interface   PersonQ){ public   void   sayHelloQ)Q}

    Public   class   PersonImplA   implements   Person{ public   PersonImplAQ){}

    public   void   sayHelloQ){     System.out.printlnQ?#8220;HelloQ?#8221;Q;} }

    Public   class   PersonImplB   implements   Person{ public   PersonImplBQ){}

    public   void   sayHelloQ){     System.out.printlnQ?#8220;Nice   to   meet   youQ?#8221;Q;} }

    客户端:Person   p   =   Naming.lookupQ?#8220;PersonService”Q;p.sayHelloQ)Q?/p>

    p几段代码包含了几乎所有的实现技术,大家怿么?客户端请求一个say   hello服务Q?a class="channel_keylink" target="_blank">服务?/a>q行时接到这个请求,利用Java反射机制的Class.newInstanceQ)q回一个对象,但客L不知道服务器q回的是 ImplAq是ImplBQ它接受用的参数{֐是PersonQ它知道实现了Person接口的对象一定有sayHelloQ)ҎQ这意味着客户端ƈ不知道服务器真正如何d现的Q但它通过了解Person接口明确了它要用的服务方法名字叫做sayHelloQ)?/p>

    如此cLQ服务器只需要暴露自q接口出来供客LQ所有客L可以自己选择需要的服务。这像馆只要拿出自己的菜单出来让客户选择Q就可以在后台厨房一道道的按需做出来,它怎么做的通常是不让客L道的Q(传菜谱吧,^_^Q?/p>

    最后一Ҏ我调用lookupQ查找一个叫PersonService名字的对象,服务器只要看到这个名字,在自q目录Q相当于电话)中找到对应的对象名字提供服务可以了Q这个目录就叫做JNDI   QJava命名与目录接口)Q相信大家也听过的?/p>

    有兴的朋友不妨自己做个RMI的应用,很多前辈的博客中有简单的例子。提CZ下利用Jdk的bin目录中rmi.exe?rmiregistry.exe两个命o可以自己徏起一个服务器Q提供远E服务。因Z子很Ҏ找,我就不自׃D例子了!

    2.   JVM沙箱&框架

    RMI|唆得太多了Q实在是力x它说清楚Q希望对大家有帮助。最后的最后,l大家简单讲一下JVM框架Q我们叫做Java沙箱。Java沙箱的基本组件如下:aQ?nbsp;  c装载器l构bQ?nbsp;  class文g验器cQ?nbsp;  内置于Java虚拟机的安全ҎdQ?nbsp;  安全理器及Java   API

    其中c装载器?个方面对Java沙箱起作用:a.   它防止恶意代码去q涉善意的代码b.   它守护了被信ȝcd边界c.   它将代码归入保护域,定了代码可以进行哪些操?/p>

    虚拟Zؓ不同的类加蝲器蝲入的cL供不同的命名I间Q命名空间由一pd唯一的名U组成,每一个被装蝲的类有一个名字,q个命名I间是由Java虚拟Zؓ每一个类装蝲器维护的Q它们互怹间甚至不可见?/p>

    我们常说的包QpackageQ是在Java虚拟机第2版的规范W一ơ出玎ͼ正确定义是由同一个类装蝲器装载的、属于同一个包、多个类型的集合。类装蝲器采用的机制是双亲委z模式。具体的加蝲器框架我在Java杂谈Q一Q中已经解释q了Q当时说最外层的加载器是AppClassLoaderQ其实算上网l层的话AppClassLoader也可以作为parentQ还有更外层的加载器URLClassLoader.Z防止恶意d由URL加蝲q来的类文g我们当然需要分不同的访问命名空_q且制定最安全的加载次序,单来说就是两点:

    a.   从最内层JVM自带cd载器开始加载,外层恶意同名cd不到先加载而无法用b.   ׃严格通过包来区分了访问域Q外层恶意的c通过内置代码也无法获得权限访问到内层c,破坏代码p然无法生效?/p>

    附:关于Java的^台无x,有一个例子可以很明显的说明这个特性:一般来_C?a class="channel_keylink" target="_blank">C++中的int占位宽度是根据目标^台的字长来决定的Q这意味着针对不同的^台编译同一?a class="channel_keylink" target="_blank">C++E序在运行时会有不同的行为。然而对?Java中的int都是32位的二进制补码标识的有符h敎ͼ而float都是遵守IEEE   754点标准?2位QҎ?/p>

Sky Yi 2008-09-12 17:20 发表评论
]]>
~程l验pd-Java学习杂谈Q五Q?/title><link>http://www.tkk7.com/hnicypb/articles/228621.html</link><dc:creator>Sky Yi</dc:creator><author>Sky Yi</author><pubDate>Fri, 12 Sep 2008 09:19:00 GMT</pubDate><guid>http://www.tkk7.com/hnicypb/articles/228621.html</guid><wfw:comment>http://www.tkk7.com/hnicypb/comments/228621.html</wfw:comment><comments>http://www.tkk7.com/hnicypb/articles/228621.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/hnicypb/comments/commentRss/228621.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/hnicypb/services/trackbacks/228621.html</trackback:ping><description><![CDATA[  q一准备讲一讲Xml解析包和<a class="channel_keylink" target="_blank">Java</a>   SwingQ然后下一再讲java.security包关?a class="channel_keylink" target="_blank">Java</a>沙箱<a class="channel_keylink" target="_blank">安全</a>机制和RMI机制Q再q入J2ee的部分,暂时做q样的计划了? <p>    <strong>1.   Java关于XML的解?/strong></p> <p>    怿大家对XML都不陌生Q含义是可扩展标记语a。本w它也就是一个数据的载体以树状表现Ş式出现。后来慢慢的数据变成了信息,区别是信息可以包括可变的状态从而针对程序硬~码的做法变革ؓ针对l一接口编码而可变状态作Z息进入了XML?a class="channel_keylink" target="_blank">存储</a>。这h变状态实现扩展的唯一工作是在XML中添加一D|本信息就可以了,代码不需要改动也不需要重新编译。这个灵zL是XML诞生时候谁也没惛_的?/p> <p>    当然Q如果接口要能提取XML中配|的信息需要程序能解析规范的XML文gQJava中当然要提高包对q个行ؓq行有利支持。笔者打讲到的两个包是 org.w3c.dom和javax.xml.parsers和。(大家可以览一下这些包中间的接口和cd义)</p> <p>    Javax.xml.parsers包很单,没有接口Q两个工厂配两个解析器。显然解析XML是有两种方式的:DOM解析和SAX解析。本质上q没有谁好谁不好Q只是实现的思想不一LŞ了。给一个XML文g的例子:</p> <p>    <Qxml   version=“1.0”   encoding=“UTF-8”   > </p> <p>    <root   > </p> <p>    <child     name=“Kitty”   > </p> <p>    A   Cat </p> <p>    </child   > </p> <p>    </root   ></p> <p>    所谓DOM解析的思\是把整个树状囑֭入内存中Q需要那个节点只需要在树上搜烦可以读到节点的属性,内容{,q样的好处是所有节点皆在内存可以反复搜索重复用,~点是需要消耗相应的内存I间?/p> <p>    自然SAX解析的思\是Z克服DOM的缺点,以事件触发ؓ基本思\Q顺序的搜烦下来Q碰CElement之前触发什么事Ӟ到之后做什么动作。由于需要自己来写触发事件的处理ҎQ所以需要借助另外一个自定义的HandlerQ处于org.xml.sax.helpers包中。它的优点当然是不用整个包都d内存Q缺点也是只能顺序搜索,走完一遍就得重来?/p> <p>    大家很容易就能猜刎ͼ接触到的J2ee框架用的是哪一U,昄是DOM.因ؓcMStrutsQHibernate框架配置文g毕竟是很的一部分配置信息Q而且需要频J搜索来dQ当然会采用DOM方式Q其实SAX内部也是用DOM采用的结构来<a class="channel_keylink" target="_blank">存储</a>节点信息的)。现在无论用什么框Ӟq真隑֏C?SAX来解析XML的技术了Q如果哪位仁兄知道,误W者也学习学习?/p> <p>    既然解析方式有了Q那么就需要有解析的存储位|。不知道大家是否发现org.w3c.domq个包是没有实现cd部都是接口的。这里笔者想说一下Java 如何对XML解析是Jdk应该考虑的事Q是它的责Q。而w3cl织是维护定义XML标准的组l,所以一个XMLl构是怎么L由w3c说了,它不兛_ Java如何d玎ͼ于是乎规定了所有XML存储的结构应该遵循的规则Q这是org.w3c.dom里全部的接口目的所在。在W者看来,单理解接口的概念是实现者必遵守的原则?/p> <p>    整个XML对应的结构叫Document、子元素对应的叫做Element、还有节点相关的Node、NodeList、Text、Entity?CharacterData、CDATASection{接口,它们都可以在XML的语法中间找到相对应的含义。由于这里不是讲解XML基本语法Q就不多介绍了。如果大家感兴趣Q笔者也可以专门写一关于XML的语法规则帖与大家分享一下?/p>    <strong>2.   Java   Swing</strong> <p>    Swing是一个让人又爱又恨的东西Q可׃处在于上手很ҎQ较AWT比v来Swing提供的界面功能更加强大,可恨之处在于~复杂的界面工作量实在是巨大。笔者写q超q?000行的Swing界面Q感觉用户体验还不是那么优秀。最q又写过过6000行的Q由于功能模块多了,整体效果q只是一般般。体会最q׃个字Q篏Q?nbsp;  所以大家现在都陆箋不怎么用Swing在真正开发的目上了Q太多界面技术可以取代它了。笔者去写也是迫于无奈组里面大家都没写过Q我不入地域谁入Q?/p> <p>    管Swing慢慢的在被h忽略Q特别是随着B/S慢慢的在ҎC/SQ笔者倒是很愿意站出来为Swing正n。每一Ҏ术的掌握l不是ؓ了流行时跟风。真正喜ƢJava的朋友们q是应该好好体会一下SwingQ相信在校的很多学生也很多在学习它。很可能从Jdk   1.1?.2走过来的很多大学老师可能是最不熟悉它的?/p> <p>    Swing提供了一l轻lgl称为JComponentQ它们与AWTlg的最大区别是JComponent全部都是ContainerQ?Container的特Ҏ里面可以装蝲别的lg。在Swinglg中无论是JButton、JLabel、JPanel、JList{都可以再装入Q何其他组件。好处是E序员可以对Swinglg实现“再开?#8221;Q针对特定需求构q按钮、标{、画ѝ列表之cȝ特定lg?/p> <p>    有轻自然有重,那么ȝ件和重组件区别是Q重lg表现出来的Ş态因操作pȝ不同而异Q轻lg是Swing自己提供GUIQ在跨^台的时候最大程度的保持一致?/p> <p>    那么在编E的时候要注意一些什么呢Q笔者谈谈自q几点l验Q?/p> <p>    a.   明确一个概念,只有Framelg才可以单独显C的Q也许有Z说JOptionPane里面的静态方法就实现了单独窗口出玎ͼ但追L代码会发现其实现实出来的Dialog也需要依托一个FrameH体Q如果没有指定就会默认生一个然后装载这个Dialog昄出来?/p> <p>    b.   JFrame是由q么几部分组成:最底下一层JRootPaneQ上面是glassPane   Q一个JPanelQ和layeredPane   Q一个JLayeredPaneQ,而layeredPane又由contentPaneQ一个JPanelQ和menuBar构成。我们的lg都是加在 contentPane上,而背景图片只能加在layeredPane上面?nbsp;  至于glassPane是一个透明的覆盖了contentPane的一层,在特定效果中被利用到来记录鼠标坐标或掩饰组件?/p> <p>    c.   Z增强用户体验Q我们会在一些按钮上d快捷键,但Swing里面通常只能识别键盘的Alt键,要加入其他的快捷键,必须自己实现一个ActionListener.</p> <p>    d.   通过setLayoutQnullQ可以得所有组件以setBoundsQ)的四个参数来_定位各自的大、位|,但不推荐使用Q因为好的编E风g应该在Swing代码中硬~码具体数字Q所有的数字应该以常数的形式l一存在一个静态无实例资源cL件中。这个静态无实例cȝ一负责Swing界面的风|包括字体和颜色都应该包括q去?/p> <p>    e.   好的界面设计有一条Golden   RuleQ?nbsp;  用户不用M手册通过数试p学会使用软g。所以尽量把按钮以菜单的形式Q不是右键菜单q是H体自带剙菜单Q呈现给֮Q除非是频繁点击的按钮才有必要直接呈现在界面中?/p> <p>    其实Swing的功能是相当强大的,只是现在应用不广泛,专门ȝI大概是要花不少旉的。笔者在各网站论坛浏览关于Swing的技巧文章还是比较可信的Q自己所学非常有限,各h体会对Swing各个lg的掌握就是一个实늧累的q程?/p> <img src ="http://www.tkk7.com/hnicypb/aggbug/228621.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/hnicypb/" target="_blank">Sky Yi</a> 2008-09-12 17:19 <a href="http://www.tkk7.com/hnicypb/articles/228621.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>~程l验pd-Java学习杂谈Q四Q?/title><link>http://www.tkk7.com/hnicypb/articles/228619.html</link><dc:creator>Sky Yi</dc:creator><author>Sky Yi</author><pubDate>Fri, 12 Sep 2008 09:18:00 GMT</pubDate><guid>http://www.tkk7.com/hnicypb/articles/228619.html</guid><wfw:comment>http://www.tkk7.com/hnicypb/comments/228619.html</wfw:comment><comments>http://www.tkk7.com/hnicypb/articles/228619.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/hnicypb/comments/commentRss/228619.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/hnicypb/services/trackbacks/228619.html</trackback:ping><description><![CDATA[  W三讲的是反射机制集合框架之类的,q次打算讲讲自己对反序列化和多线E的理解。希望能对大家学?a class="channel_keylink" target="_blank">Java</a>起到帮助Q? <p>    <strong>1.关于序列化和反序列化</strong></p> <p>    应该大家都大概知?a class="channel_keylink" target="_blank">Java</a>中序列化和反序列化的意思,序列化就是把一个Java对象转换成二q制q行盘上传输或者网l流的传输,反序列化的意思就是把q个接受到的二进制流重新l装成原来的对象逆过E。它们在Java中分别是通过ObjectInputStream?nbsp;  ObjectInputStreamq两个类来实现的Q以下分别用ois和oos来简Uͼ?/p> <p>    oos的writeObjectQ)Ҏ用来执行序列化的q程Qois的readObjectQ)用来执行反序列化的过E,在传输二q制之前,需要讲q两个高层流对象q接到同一个Channel上,q个Channel可以是磁盘文Ӟ也可以是socket底层。所以无论用哪种方式Q底层流对象都是以构造函数参数的形式传递进oos和oisq两个高层流Q连接完毕了才可以进行二q制数据传输的。例子:</p> <p>    可以是文件流通道</p> <p>    file   =   new   FileQ?#8220;CQ?data.dat”Q;</p> <p>    oos   =   new   ObjectOutputStreamQnew   FileOutputStreamQfileQ)Q?/p> <p>    ois   =   new   ObjectInputStreamQnew   FileInputStreamQfileQ)Q?/p> <p>    或者网l流通道</p> <p>    oos   =   new   ObjectOutputStreamQsocket.getOutputStreamQ)Q;</p> <p>    ois   =   new   ObjectInputStreamQsocket.getInputStreamQ)Q;</p> <p>    不知道大家是否注意到oosL在ois之前定义Q这里不希望大家误解q个序是固定的么?回答是否定的Q那么有序要求么?回答是肯定的。原则是什么呢Q?/p> <p>    原则是互相对接的输入/输出之间必Loutput先初始化然后再input初始化Q否则就会抛异常。大家肯定会问ؓ什么?只要E微看一看这两个cȝ源代码文件就大概知道了,output的d很简单,只要把对象{换成二进制往通道中写可以了Q但input需要做很多准备工作来接受ƈ最l重l这个ObjectQ所以ObjectInputStream的构造函C需要用到output初始化发送过来的header信息Q这个方法叫?nbsp;  readStreamHeaderQ)Q它会去读两个Short值用于决定用多大的缓存来存放通道发送过来的二进制流Q这个缓存的size因jre的版本不同是不一L。所以output如果不先初始化,input的构造函数首先就无法正确q行?/p> <p>    对于上面两个例子Q第一个顺序是严格的,W二个因为oos和oisq接的已l不是对方了Q而是socket另外一端的,需要严格按照另外一方对接的output先于对接的input打开才能利q行?/p> <p>    q个writeObject和readObject本n是U程<a class="channel_keylink" target="_blank">安全</a>的,传输q程中是不允许被q发讉K的。所以对象能一个一个接q不断的传过来,有很多h在运行的时候会到EOFExceptionQ?nbsp;  然后百思不得其解,dU论坛问解决Ҏ。其实笔者这里想_q个异常不是必须声明的,也就是说它虽然是异常Q但其实是正常运行结束的标志。EOF表示d了文件尾Q发送结束自然连接也断开了。如果这影响C你程序的正确性的话,请各位静下心来看看自q序的业务逻辑Q而不要把注意力狭隘的聚集在发送和接受的方法上。因为笔者也被这Lbug困扰?整天Q被很多论坛的帖子误解了很多ơ最后得出的教训。如果在while循环中去readObjectQ本质上是没有问题的Q有对象数据来就会读Q没有就自动d。那么抛出EOFException一定是因ؓq接断了q在l箋readQ什么原因导致连接断了呢Q一定是业务逻辑哪里存在错误Q比如NullPoint?nbsp;  ClassCaseException、ArrayOutofBoundQ即使程序较大也没关p,最多只要单步调适一ơ就能很快发现bugq且解决它?/p> <p>    难怪一位程序大师说q:解决问题90Q靠l验Q?Q靠技术,剩下5Q靠q气Q真是金玉良aQ笔者大概查阅过不下30讨论在while循环中?nbsp;  readObject抛出EOFExceptionde   的帖子,大家都盲目的d注解释这个名词、反序列化的行ؓ或反对这样写而没有一个h认ؓEOF是正的行ؓQ它其实很老实的在做它的事情。ؓ什么大安忽略了真正出错误的地方呢Q两个字Q经验!</p>   <strong>2.关于Java的多U程~程</strong> <p>    关于Java的线E,初学或者接触不q大概也能知道一些基本概念,同时又会很迷惑线E到底是怎么回事Q如果有己已l懂了不妨来回答下面的问题:a.   A对象实现Runnable接口QA.startQ)q行后所谓的U程对象是谁Q是A么?</p> <p>    b.   U程的waitQ)、notifyQ)Ҏ到底是做什么时候用的,什么时候用Q?/p> <p>    c.   Z么线E的suspendҎ会被标注q时Q不推荐再用,U程q能挂v么?</p> <p>    d.   Z同步我们会对U程Ҏ声明Synchronized来加锁在对象上,那么如果父类的fQ)Ҏ加了SynchronizedQ子c重写fQ)Ҏ必须也加Synchronized么?如果子类的fQ)Ҏ重写时声明Synchronizedq调用super.fQ)Q那么子cd象上到底有几把锁呢?会因为竞争生死锁么Q?/p> <p>    首先W一点,U程跟对象完全是两回事,虽然我们也常说线E对象。但当你用runQ)和startQ)来启动一个线E之后,U程其实跟这个承了   Thread或实CRunnable的对象已l没有关pMQ对象只能算内存中可用资源而对象的Ҏ只能内存正文区可以执行的代码段而已。既然是资源和代码段Q另外一个线E当然也可以去访问,main函数执行p会启动两个U程Q一个我们称之ؓȝE,q一个是垃圾攉器的U程Q主U程l束意味着E序l束Q可垃圾攉器线E很可能正在工作?/p> <p>    W二点,waitQ)和sleepQ)cMQ都是让U程处于d状态暂停一D|_不同之处在于wait会释攑ֽ前线E占有的所有的锁,?nbsp;  sleep不会。我们知道获得锁的唯一Ҏ是进入了Synchronized保护代码D,所以大家会发现只有SynchronizedҎ中才会出?nbsp;  waitQ直接写会给警告没有获得当前对象的锁。所以notify跟wait配合使用Qnotify会重新把锁还l阻塞的U程重而其l执行,当有多个对象wait了,notify不能定唤醒哪一个,必经锁只有一把,所以一般用notifyAllQ)来让它们自己Ҏ优先U等竞争那唯一的一把锁Q竞争到的线E执行,其他U程只要l箋wait.</p> <p>    从前Java允许在一个线E之外把U程挂vQ即调用suspendҎQ这L操作是极?a class="channel_keylink" target="_blank">安全</a>的。根据面向对象的思想每个对象必须对自q行ؓ负责Q而对自己的权力进行封装。如果Q何外步对象都能ɾU程被挂赯阻塞的话,E序往往会出现؜乱导致崩溃,所以这LҎ自然是被毙掉了啦?/p> <p>    最后一个问题比较有意思,首先回答的是子类重写fQ)Ҏ可以加Synchronized也可以不加,如果加了而且q内部调用了super.f   Q)的话理论上是应该对同一对象加两把锁的,因ؓ每次调用SynchronizedҎ都要加一把,调用子类的f首先加了一把,q入Ҏ内部调用父类?nbsp;  f又要加一把,加两把不是互斥的么?那么调父cf加锁不就必须永远{待已经加的锁释放而造成死锁么?实际上是不会的,q个机制叫重q入Q当父类的fҎ试图在本对象上再加一把锁的时候,因ؓ当前U程拥有q个对象的锁Q也可以理解为开启它的钥匙,所以同一个线E在同一对象上还没释放之前加W二ơ锁是不会出问题的,q个锁其实根本就没有加,它有了钥匙,不管加几把还是可以进入锁保护的代码段Q畅通无阻,所以叫重进入,我们可以单认为第二把锁没有加上去?/p> <p>    总而言之,Synchronized的本质是不让其他U程在同一对象上再加一把锁?/p> <img src ="http://www.tkk7.com/hnicypb/aggbug/228619.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/hnicypb/" target="_blank">Sky Yi</a> 2008-09-12 17:18 <a href="http://www.tkk7.com/hnicypb/articles/228619.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>~程l验pd-Java学习杂谈Q三Q?http://www.tkk7.com/hnicypb/articles/228618.htmlSky YiSky YiFri, 12 Sep 2008 09:17:00 GMThttp://www.tkk7.com/hnicypb/articles/228618.htmlhttp://www.tkk7.com/hnicypb/comments/228618.htmlhttp://www.tkk7.com/hnicypb/articles/228618.html#Feedback0http://www.tkk7.com/hnicypb/comments/commentRss/228618.htmlhttp://www.tkk7.com/hnicypb/services/trackbacks/228618.htmlJava杂记了,庆幸前两一直得到论坛朋友们的支持鼓励,q望大家l箋指正不之处。笔者也一直望通过q样方式清醒的自审,来寻找自己技术上的不之处,希望和共同爱?a class="channel_keylink" target="_blank">Java的同仁们一h高?

    前两ơ分别讲qC关于jvm、jdk、jre、collection、classLoader和一些Design   Pattern的自我理解。这ơ仍然不准备开始过渡到j2ee中,因ؓ觉得q有一些琐的j2se的问题没有ȝ完毕?/p>

    1.   关于Objectcȝ?/strong>

    大家都知道Object是所有Javacȝ基类Q?nbsp;  意味着所有的Javac都会承了Object?1个方法。徏议大家去看看Object?nbsp;  11个成员函数的源代码,׃知道默认的实现方式。比如equalsҎQ默认实现就是用"=="来比较,即直接比较内存地址Q返回true   或?nbsp;  false.而toStringQ)ҎQ返回的串组成方式是Q?

    "getClassQ)。getNameQ)   +   "@"   +   Integer.toHexStringQhashCodeQ)Q?其实不用我过多的解释Q大安能看懂这个串的组成。接下来再看看hashCodeQ)Qpublic   native   int   hashCodeQ)Q?/p>

    ׃是nativeҎQ跟OS的处理方式相养I源代码里仅仅有一个声明Ş了。我们有兴趣的话完全可以LI它的hashCode到底是由OS怎么样生的呢?但笔者徏议最重要的还是先C使用它的几条原则吧!首先如果equalsQ)Ҏ相同的对象具有相通的hashCodeQ但equals   Q)对象不相通的时候ƈ不保证hashCodeQ)Ҏq回不同的整数。而且下一ơ运行同一个程序,同一个对象未必还是当初的那个hashCodeQ)   哦?/p>

    其余的方法呢QnofigyQ)、notifyAllQ)、cloneQ)、waitQ)都是nativeҎ的,说明依赖于操作系l的实现。最后一个有的Ҏ是finalizeQ)Q类?a class="channel_keylink" target="_blank">C++的析构函敎ͼ{֐是protectedQ证明只有承扩展了才能使用Q方法体是空的,默示什么也不做。它的作用据W者的了解仅仅是通知JVM此对象不再用,随时可以被销毁,而实际的销毁权q是在于虚拟机手上。那么它真的什么也不做麽?未必Q实际上如果是线E对象它会导致在一定范围内该线E的优先U别提高Q导致更快的被销毁来节约内存提高性能。其实从常理来说Q我们也可以大概q样猜测出jvm做法的目的?/p>

    2.   关于重蝲hashCodeQ)与Collection框架的关p?/strong>

    W者曾l听一位搞Java培训多年的前辈说在他看来hashCodeҎ没有M意义Q仅仅是Z配合证明h同样的hashCode会导致equals   Ҏ相等而存在的。连有的前辈都犯q样的错误,其实说明它还是满Ҏ被忽略的。那么hashCodeQ)Ҏ到底做什么用Q?/p>

    学过数据l构的课E大安会知道有一U结构叫hash   tableQ目的是通过l每个对象分配一个唯一的烦引来提高查询的效率。那么Java也不会肆意扭曲改变这个概念,所以hashCode唯一的作用就是ؓ支持数据l构中的哈希表结构而存在的Q换句话_也就是只有用到集合框架的   Hashtable、HashMap、HashSet的时候,才需要重载hashCodeQ)ҎQ这h能得我们能Zؓ的去控制在哈希结构中索引是否相等。笔者D一个例子:曄Z写一个求解类E序Q需要随机列?Q?Q?Q?l成的不同排列组合,所以笔者写了一个数l类用int[]来存l合l果Q然后把随机产生的组合加入一个HashSet中,是惛_用HashSet不包括重复元素的特点。可是HashSet怎么判断是不是重复的元素呢?当然是通过   hashCodeQ)q回的结果是否相{来判断啦,可做一下这个实验:

    int[]   A   =   {1Q?Q?Q?}Q?/p>

    int[]   B   =   {1Q?Q?Q?}Q?/p>

    System.out.printlnQA.hashCodeQ)Q;

    System.out.printlnQB.hashCodeQ)Q;

    q明明是同一U组合,却是不同的hashCodeQ加入Set的时候会被当成不同的对象。这个时候我们就需要自己来重写hashCodeQ)Ҏ了,如何写呢Q其实也是基于原始的hashCodeQ)Q毕竟那是操作系l的实现Q?nbsp;  扑ֈ盔R对象唯一的标识,实现方式很多Q笔者的实现方式是:首先重写了toStringQ)ҎQreturn     A[0]“+”   A[1]“+”   A[2]“+”   A[3]Q?nbsp;  //昄上比较直观然后利用toStringQ)来计hashCodeQ)Qreturn     this.toStringQ)。hashCodeQ)Q这样上qA和Bq回的就都是“1234”Q在toStringQ)。hashCodeQ)Q由于String在内存中的副本是一LQ?#8220;1234”。hashCodeQ)q回的一定是相同的结果?/p>

    说到q,怿大家能理解得比我更好Q今后千万不要再误解hashCodeQ)Ҏ的作用?/p>  3.   关于Classcȝ成员函数与Java反射机制

    很早刚接触Java听很多老师说过Java的动态运行时机制、反机制等。确实它们都是Java的显著特点,q行时加载笔者在W一介l过了,现在惌讲反机制。在Java中,主要是通过java.lang包中的ClasscdMethodcL实现内存反射机制的?/p>

    熟悉C++的h一定知道下面这样在C++中是做不到的Q?nbsp;  q行时以字符串参C递一个类名,可以得到这个类的所有信息,包括它所有的ҎQ和Ҏ的详l信息。还可以实例化一个对象,q过查到的方法名来调用该对象的Q何方法。这是因为Java的类在内存中除了C++中也有的静态动态数据区之外Q还包括一份对c自w的描述Q也正是通过q描qC的信息,才能帮助我们才运行时d里面的内容,得到需要加载目标类的所有信息,从而实现反机制。大家有没有惌当我们需要得C个JavaBean的实例的时候,怎么知道它有哪些属性呢Q再明显单不q的例子是自己写一个JavaBean的解析器Q?/p>

    a.   通过Class.forNameQ?#8220;Bean的类?#8221;Q得到Class对象Q例如叫ABeanClass

    b.   通过ABeanClass的getMethodsQ)ҎQ得到Method[]对象

    c.   按照规范所有getҎ名后的单词就代表着该Bean的一个属?/p>

    d.   当已l知道一个方法名Q可以调用newInstanceQ)得到一个实例,然后通过invokeQ)Ҏ方法的名字和方法需要用的参C递进去,可以动态调用此Ҏ?/p>

    当然q有更复杂的应用Q这里就不赘qͼ大家可以参考ClasscdMethodcȝҎ?/p>

    4.   坦言Synchronize的本?/strong>

    Synchronize大家都知道是同步、加锁的意思,其实它的本质q没有大家想得那么复杂。声明Synchronize的方法被调用的时候,锁其实是加蝲对象上,当然如果是静态类则是加在cM的锁Q调用结束锁被解除。它的实现原理很单,仅仅是不让第二把锁再ơ被加在同一个对象或cMQ仅此而已。一个简单的例子以说明问题Q?/p>

    class   A{

    synchronized   void   fQ){}

    void   gQ){}

    }

    当A的一个对象a被第一个线E调用其fQ)Ҏ的时候,W二个线E不能调用a的synchronizedҎ例如fQ)Q因为那是在试图在对象上加第二把锁。但调用gQ)却是可以的,因ؓq没有在同一对象上加两把锁的行ؓ产生?/p>

    q样大家能理解了麽?明白它的原理能更好的帮助大家设计同步机制Q不要滥用加锁?/p>

Sky Yi 2008-09-12 17:17 发表评论
]]>
~程l验pd-Java学习杂谈Q二Q?http://www.tkk7.com/hnicypb/articles/228617.htmlSky YiSky YiFri, 12 Sep 2008 09:16:00 GMThttp://www.tkk7.com/hnicypb/articles/228617.htmlhttp://www.tkk7.com/hnicypb/comments/228617.htmlhttp://www.tkk7.com/hnicypb/articles/228617.html#Feedback0http://www.tkk7.com/hnicypb/comments/commentRss/228617.htmlhttp://www.tkk7.com/hnicypb/services/trackbacks/228617.htmlJava动态加载机制、classLoader原理和关于jdk和jre三个问题。这ơgl着讲一些具体的cdQ?

    1.   关于集合框架c?/strong>

    怿学过Java的各位对q个名词q不陌生Q对   java.util.*q个package肯定也不陌生。不知道大家查询API的时候怎么d视或者分析其中的一个packageQ每个包最重要的两个部分就是interfaces和classesQ接口代表了它能做什么,实现cd代表了它如何d。关注实现类之前Q我们应该先理解清楚它的来源接口Q不在j2seq是j2ee中,都应该是q样。那么我们先看这三个接口QList、Set、Map.也许有些Z太熟悉这三个名字Q但怿大部分h都熟悉ArrayListQLinkedListQTreeSetQHashSetQHashMapQ?nbsp;    Hashtable{实现类的名字。它们的区别也是满容易理解的QList攑֏以重复的对象集合QSet放不可重复的对象l合Q而Map则放   <KeyQValue   > q样的名值对Q?nbsp;  Key不可重复QValue可以。这里有几个Ҏh的问题:

    到底Vector和ArrayListQHashtable和HashMap有什么区别?

    很多面试官喜Ƣ问q个问题Q其实更专业一点应该这样问Q新集合框架和旧集合框架有哪些区别?新集合框架大家可以在q些包中找since   jdk1.2的,之前的如vector和Hashtable都是旧的集合框架包括的类。那么区别是Q?/p>

    a.   新集合框架的命名更加U学合理。例如List下的ArrayList和LinkedList b.   新集合框架下全部都是非线E?a class="channel_keylink" target="_blank">安全的。徏议去jdk里面包含的源代码里面自己M自看看vector和ArrayList的区别吧。当然如果是jdk5.0之后的会比较隄一点,因ؓ又加入了泛型的语法,cMc++的template语法?/p>

    那么大家是否惌Z么要从旧集合框架默认全部加锁防止多线E访问更新到新集合框架全部取消锁Q默认方式支持多U程Q(当然需要的时候可以用collections的静态方法加锁达到线E?a class="channel_keylink" target="_blank">安全Q?/p>

    W者的观点是Q何技术的发展都未必是遵@它们的初LQ很多重大改变是受到客观环境的媄响的。大家知道Java的初hZ么而开发的麽?是ؓ嵌入?/a>E序开发的。记得上一讲到classLoader机制麽?那正是ؓ了节U?a class="channel_keylink" target="_blank">嵌入?/a>开发环境下内存而设计的。而走C天,Java成了Z心中?a class="channel_keylink" target="_blank">互联|?/a>诞生的语a?a class="channel_keylink" target="_blank">互联|?/a>意味着什么?多线E是必然的趋ѝ客观环境在变,Java技术也随着飞速发展,D来脱d的初街据说Sun公司其实L的是J2seQ结果又是由于客观环境媄响,J2se几乎遗忘Q留在大家谈论焦点的一直是j2ee.

    技术的l节q里׃多说了,只有用了才能真正理解。解释这些正是ؓ了帮助大家理解正在学的和要学的M技术。之后讲j2ee的时候还会再讨论?/p>

    多扯句题外话Q几十年前的IT巨h是IBMQMainframe市场无h可比。微软如何打败IBMQ正是由于硬仉速发展,对个人PC的需求这个客观环境,让微软通过OSUCؓ了第二个巨h。下一个打败微软的呢?Google.如何做到的?如果微Yq不和IBM争大型机QGoogle借着互联|飞速发展这个客观环境作为决定性因素,避开跟微软争OSQ而是走搜索引擎这条\Q称为第3个巨人。那么第4个巨人是谁呢Q很多专安a在亚洲或者中国出玎ͼ   WhateverQ客观环境变化趋势才是决定大方向的关键。当然笔者也希望会出现在中国?/p>  2.   关于Java设计模式

    w边的很多在看GOF?3U设计模式,g学习它无论在学校q是在职场,都成了一U流行风气。我不想列D解释q?3UDesign   PatternQ?nbsp;  我写q些的初衷一直都是谈自己的经历和看法Q希望能帮助大家理解?/p>

    首先我觉得设计模式只是对一c问题的一U通用解决办法Q只要是面向对象的编E预a都可以用得上q?3U。理解它们最好的Ҏ是亲自d每一U,哪怕是一个简单的应用p够了。如果代码实CC住的话,记忆它们对应的UML图会是一个比较好的办法,当然前提是必M解UML.同时最好能利用Java自n的类库帮助记忆,例如比较常用的观察者模式,在java.util.*有现成的Observer接口和Observableq个实现c,看看源代码相信就_理解观察者模式了。再比如装饰器模式,大家只要写几个关于java.io.*的程序就可以完全理解什么是装饰器模式了。有很多得刚入门的时候不该接触设计模式,比如囄设计丛书pd很出名的那本《Java设计模式》,作者:   Steven   John   MetskerQ大部分例子老实说o现在的我也很qh。但我仍然不同意入门跟学习设计模式有M冲突Q只是我们需要知道每U模式的概念的和典型的应用,q样我们在第一ơ编?nbsp;  FileOutputStream、BufferedReader、PrintWriter的时候就能感觉到原来设计模式L们如此之q,而且q不是多么神U的东西?/p>

    另外Q在学习某些模式的同Ӟ反而更能帮助我们理解javacd的某些特炏V例如当你编写原型(PrototypeQ模式的时候,你必M解的?nbsp;  java.lang.Cloneableq个接口和所有类的基cObject的cloneQ)q个Ҏ。即深copy和浅copy的区别:Object.cloneQ)默认实现的是copyQ也是复制一份对象拷贝,但如果对象包含其他对象的引用Q不会复制引用,所以原对象和拷贝共用那个引用的对象?/p>

    深copy当然是包括对象的引用都一起复制啦。这样原对象和拷贝对象,都分别拥有一份引用对象。如果要实现深copy必首先实?nbsp;  java.lang.Cloneable接口Q然后重写cloneQ)Ҏ。因为在Object中的cloneQ)Ҏ是protected{֐的,?nbsp;  Cloneable接口的作用就是把protected攑֤到publicQ这样cloneQ)才能被重写?/p>

    那么又有个问题了Q如果引用的对象又引用了其他对象呢?q样一直判断ƈ复制下去Q是不是昑־很麻烦?曄有位前辈告诉我的Ҏ是重写cloneҎ的时候直接把原对象序列化到磁盘上再反序列化回来,q样不用判断可以得C个深copy的结果。如果大家不了解序列化的作法看一?nbsp;  ObjectOutputStream和ObjectInputStream

    归根l底Q模式只是思想上的东西Q把它当成前人ȝ的经验其实一炚w不ؓq。鼓励大家动手自己去写,例如代理模式Q可以简单的写一个Childc,   AdultcRChild要买M东西由Adult来代理实现。简单来说就是Adult里的buyQ)内部实际调用的是Child的buyQ)Q可是暴露在main函数的却是Adult.buyQ)。这样一个简单的E序p够理解代理模式的基本含义了?/p>

Sky Yi 2008-09-12 17:16 发表评论
]]>
~程l验pd-Java学习杂谈Q一Q?http://www.tkk7.com/hnicypb/articles/228616.htmlSky YiSky YiFri, 12 Sep 2008 09:15:00 GMThttp://www.tkk7.com/hnicypb/articles/228616.htmlhttp://www.tkk7.com/hnicypb/comments/228616.htmlhttp://www.tkk7.com/hnicypb/articles/228616.html#Feedback0http://www.tkk7.com/hnicypb/comments/commentRss/228616.htmlhttp://www.tkk7.com/hnicypb/services/trackbacks/228616.htmlJava也有两个q头了,永远不敢说多么精通,但也惌谈自q感受Q写lY件学院的同仁们,帮助大家在技术的道\上少一点弯路。说得伟大一Ҏ希望大家Y件学院争气,其实最主要的还是大家自w的q步提升?

    1. 关于动态加载机?/strong>

    学习Java?a class="channel_keylink" target="_blank">C++更容易理解OOP的思想Q毕?a class="channel_keylink" target="_blank">C++q؜合了不少面向q程的成分。很多h都能背出来Java语言的特点,所谓的动态加载机制等{。当然概念往往是先C而后消化的,可有多少人真正去体会q动态加载的机制Q试囑֎Lq其中的l节呢?   提供大家一个方法:在命令行H口q行JavaE序的时候,加上q个很有用的参数Q?/p>

    java   Qverbose   *.class

    q样会清晰的打印加蝲的类文gQ大部分是jdk自nq行需要的Q最后几行会明显的看到自q到的那几个类文g被加载进来的序。即使你声明了一个类对象Q不实例化也不会加蝲Q说明只有真正用到那个类的实例即对象的时候,才会执行加蝲。这h不是大家E微能明白一点动态加载了呢?^_^

    2. 关于Lclass文g原理

    大家在入门的时候在命o行窗口编译和q行Q不要借助JCreator或者Eclipse{IDEd助做那些事情。尝试自p样做Q?/p>

    javac     -classpath   yourpath   *.java

    java     -classpath   yourpath   *.class

    也许很多人都能看懂,讄classpath的目的就是告诉编译器d里寻找你的class文g?nbsp;  不过臛_W者今日才弄懂JVML询类的原理,~译器加载类要依靠classloaderQ?nbsp;  而classloader?个别,从高C分别是BootClassLoaderQ名字可能不准确Q?nbsp;  Q?nbsp;  ExtClassLoaderQ?nbsp;  AppClassLoader.

    q?个加载器分别对应着~译器去LcL件的优先U别和不同的路径QBootClassLoader对应jre/classes路径Q是~译器最优先Lclass的地?/p>

    ExtClassLoader对应jre/lib/ext路径Q是~译器次优先Lclass的地?/p>

    AppClassLoader对应当前路径Q所以也是编译器默认找class的地?/p>

    其实大家可以自己写个E序单的Q对MclassQ例如AQ调用new   AQ)。getClassQ)。getClassLoaderQ)。toStringQ)   打印出来可以看刎ͼ把class文g攑֜不同的\径下再次执行Q就会看到区别。特别注意的是如果打印出来是nullpC到了最高 BootClassLoaderQ?nbsp;  因ؓ它是C++~写的,不存在Java对应的类加蝲器的名字?/p>

    L的顺序是一U向上迂回的思想Q即如果本别找不到Q就只能LU别之上的找Q不会向下寻找。不q似乎从Jdk1.4到Jdk1.6q一特点又有改变Q没有找到详l资料。所以就不D例子了。告诉大家设计这U体pȝ是Sun公司曄的技术核心宫力先生,一个纯U华人哦Q^_^

    q样希望大家不至于迷惑ؓ什么L错找不到cLӞ不管是自己写的还是导入的W三方的jar文gQJ2ee中经帔R要导入的Q?/p>

    3. 关于jdk和jre

    大家肯定在安装JDK的时候会有选择是否安装单独的jreQ一般都会一起安装,我也大家q样做。因h能帮助大家弄清楚它们的区别:

    Jre   是java   runtime   environmentQ?nbsp;  是javaE序的运行环境。既然是q行Q当然要包含jvmQ也是大家熟悉的虚拟机啦,   q有所有javacd的class文gQ都在lib目录下打包成了jar.大家可以自己验证。至于在windows上的虚拟机是哪个文g呢?   学过MFC的都知道什么是dll文g吧,那么大家看看jre/bin/client里面是不是有一个jvm.dll呢?那就是虚拟机?/p>

    Jdk   是java   development   kitQ是java的开发工具包Q里面包含了各种cd和工兗当然也包括了另外一个Jre.     那么Z么要包括另外一个Jre呢?而且jdk/jre/bin同时有client和server两个文g夹下都包含一个jvm.dll.   说明是有两个虚拟机的。这一点不知道大家是否注意C呢?

    怿大家都知道jdk的bin下有各种javaE序需要用到的命oQ与jre的bin目录最明显的区别就是jdk下才有javacQ这一点很好理解,因ؓ jre只是一个运行环境而已。与开发无养I正因为如此,具备开发功能的jdk自己的jre下才会同时有client性质的jvm和server性质?jvmQ?nbsp;  而仅仅作行环境的jre下只需要client性质的jvm.dll够了?/p>

    记得在环境变量path中设|jdk/bin路径麽?q应该是大家学习Java的第一步吧Q?nbsp;  老师会告诉大家不讄的话javac和java是用不了的。确实jdk/bin目录下包含了所有的命o。可是有没有人想q我们用的java命oq不?jdk/bin目录下的而是jre/bin目录下的呢?不信可以做一个实验,大家可以把jdk/bin目录下的java.exe剪切到别的地方再q行 javaE序Q发C什么?一切OKQ?/p>

    那么有h会问了?我明明没有设|jre/bin目录到环境变量中啊?

    试想一下如果javaZ提供l大多数Z用,他们是不需要jdk做开发的Q只需要jre能让javaE序跑v来就可以了,那么每个客户q需要手动去讄环境变量多麻烦啊Q所以安装jre的时候安装程序自动帮你把jre的java.exedCpȝ变量中,验证的方法很单,大家看到了系l环境变量的 path最前面?#8220;%SystemRoot%\system32Q?SystemRoot%Q?#8221;q样的配|,那么再去Windows/system32下面ȝ看吧Q发C什么?有一个java.exe.

    如果能够把jdk/bin挪到system32变量前面Q当然也可以q使用jdk/jre里面的javaQ不q除非有必要Q我不徏议大家这么做。用单独的jre跑javaE序也算是客L境下的一U?a class="channel_keylink" target="_blank">试?/p>

    q下大家应该更清楚jdk和jre内部的一些联pd区别了吧Q?/p>

Sky Yi 2008-09-12 17:15 发表评论
]]>
վ֩ģ壺 91ѹۿ| ȫƴȫɫȫѴƬ| ֳִִֺƵ| ձƵ| aƬѿ| Ʒþ㽶߿ۿ| AVһ| ޾Ʒר2| ĻƷ| ޹պۺ| ؼaa**ëƬѹۿ| ޹ۺ | þþƷһ| 99ȲƷ99| պƷһ| ĻѾþ| ޹Ʒþþþ | 3344߹ۿƵҳ| ѹۿվ߲| С˵ͼƬ| ȫAëƬѿվ| ŷһëƬѿ| ޾Ʒ벻߲HE| 99þùĻ| ĻĻɫ| 91þþþþþ| ĻѾþ9һ9| AV뾫Ʒ| ѵӰ߹ۿվ| Ļ߾Ʒһ| ޾Ʒ޿| ĻӰѹۿ| һësuvÿĹվ| ˺ݺۺϾþ| Ʒþһ| ѿƷþ| ޳AVƬһ| ëƬֻѿ| ˮwww| Թ| Ļպ|