??xml version="1.0" encoding="utf-8" standalone="yes"?>
Z么要区分J2EE容器?/span>J2EE应用pȝQ?/span>
我们知道Q?/span>J2EE应用pȝ只有部v?/span>J2EE容器中才能运行,那么Z么划分ؓJ2EE容器?/span>J2EE应用pȝQ?/span>通过?/span>J2EE容器q行机制的分析(见我的电子教?/span>“EJB实用原理”Q,我们可以发现Q实际上J2EE容器分离了一般应用系l的一些通用功能Q例如事务机制、安全机制以及对象池或线E池{性能优化机制?/span>
q些功能机制是每个应用系l几乎都需要的Q因此可以从具体应用pȝ中分d来,形成一个通用的框架^収ͼ而且Q这些功能机制的设计开发有一定难度,同时q行的稳定性和快速性都非常重要Q必ȝq长旉调试和运行经验积累而成Q因此,形成了专门的J2EE容器服务器品,?/span>Tomcat JBoss?/span>Websphere?/span>WebLogic{?/span>
?/span>J2EEpȝ划分?/span>J2EE容器?/span>J2EE应用pȝ两个斚wQ我们已l看CU分散关注的思\Q?/span>separation of concernsQ?/span>
分散x
通用需求功能从不相关类之中分离出来Q同Ӟ能够使得很多cd享一个行为,一旦行为发生变化,不必修改很多c,只要修改q个行ؓ可以?/span>
AOP是q种实现分散x的编E方法,它将“x”装?/span>“斚w”中?/span>
AOP是什么?
AOP?/span>OOP的gl,?/span>Aspect Oriented Programming的羃写,意思是面向斚w~程?/span>AOP实际?/span>GoF设计模式的gl,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,AOP可以说也是这U目标的一U实现?/span>
举例Q假设有在一个应用系l中Q有一个共享的数据必须被ƈ发同时访问,首先Q将q个数据装在数据对象中Q称?/span>Data ClassQ同Ӟ有多个讉Kc,专门用于在同一时刻讉Kq同一个数据对象?/span>
Z完成上述q发讉K同一资源的功能,需要引入锁Lock的概念,也就是说Q某个时刻,当有一个访问类讉Kq个数据对象Ӟq个数据对象必须上锁LockedQ用完后q卌?/span>unLockedQ再供其它访问类讉K?/span>
使用传统的编E习惯,我们会创Z个抽象类Q所有的讉Kcȝ承这个抽象父c,如下Q?/span>
abstract class Worker{ abstract void locked(); } |
~点Q?/span>
因此Q一个新的程序结构应该是xpȝ的纵向切面,例如q个应用?/span>“?/span>”功能Q这个新的程序结构就?/span>aspectQ方面)
在这个应用中Q?/span>“?/span>”斚wQ?/span>aspectQ应该有以下职责Q?/span>
提供一些必备的功能Q对被访问对象实现加锁或解锁功能。以保证所有在修改数据对象的操作之前能够调?/span>lock()加锁Q在它用完成后Q调?/span>unlock()解锁?/span>
AOP应用范围
很明显,AOP非常适合开?/span>J2EE容器服务器,目前JBoss 4.0正是使用AOP框架q行开发?/span>
具体功能如下Q?/span>
Authentication 权限
Caching ~存
Context passing 内容传?/span>
Error handling 错误处理
Lazy loading 懒加?/span>
Debugging 调试
logging, tracing, profiling and monitoring 记录跟踪 优化 校准
Performance optimization 性能优化
Persistence 持久?/span>
Resource pooling 资源?/span>
Synchronization 同步
Transactions 事务
AOP有必要吗Q?/span>
当然Q上q应用范例在没有使用AOP情况下,也得C解决Q例?/span>JBoss 3.XXX也提供了上述应用功能Q但是没有?/span>AOP?/span>
但是Q?/span>AOP可以让我们从一个更高的抽象概念来理解Y件系l,AOP也许提供一U有价值的工具。可以这么说Q因Z?/span>AOPl构Q现?/span>JBoss 4.0的源码要?/span>JBoss 3.XҎ理解多了Q这对于一个大型复杂系l来说是非常重要的?/span>
从另外一个方面说Q好像不是所有的人都需要关?/span>AOPQ它可能是一U架构设计的选择Q如果选择J2EEpȝQ?/span>AOPx的上q通用斚w都已l被J2EE容器实现了,J2EE应用pȝ开发者可能需要更多地x行业应用斚waspect?/span>
AOP具体实现
AOP是一个概念,q没有设定具体语a的实玎ͼ它能克服那些只有单承特性语a的缺点(?/span>JavaQ,目前AOP具体实现有以下几个项目:
AspectJ (TM)Q 创徏?/span>Xerox PARC. 有近十年历史Q成?/span>
~点Q过于复杂;破坏装Q需要专门的Java~译器?/span>
动?/span>AOPQ?/span>JDK的动态代?/span>API或字节码Bytecode处理技术?/span>
Z动态代?/span>API的具体项目有Q?/span>
JBoss 4.0 JBoss 4.0服务?/span>
nanning q是以中国南宁命名的一个项目,搞不清楚Z么和中国相关Q是中国人发LQ?/span>
Z字节码的目有:
aspectwerkz
spring Q?/span>
在以后其它文章中Q我l对AOP概念q行分析Q和大家一起学习进步?/span>
参考资料:
http://www.voelter.de/data/articles/aop/aop.html
Aspect-Oriented_Java_Development.pdf
在struts+hibernateq种l构中,是不应该把Hibernate产生的PO直接传递给JSP的,不管他是IteratorQ还是ListQ这是一个设计错误?
我来谈谈在J2EE架构中各层的数据表示ҎQ?
◆Web层的数据表示是FormBeanQ数据来源于HTML Form POST
◆业务层的数据表C是VO
◆持久层的数据表C是POQ其数据来源于数据库Q持久层的数据表CZ如CMP
在一个规范的J2EE架构中,不同层的数据表示应该被限制在层内Q而不应该扩散到其它层Q这样可以降低层间的耦合性,提高J2EE架构整体的可l护性和可扩展性。比如说Web层的逻辑q行了修改,那么只需要修改FormBean的结构,而不需要触动业务层和持久层的代码修攏V同LQ当数据库表q行了小的调_那么也只需要修Ҏ久层数据表示Q而不需要触动业务层代码和Web层代码?
不过׃Hibernate的强大功能,例如动态生成POQPO的状态管理可以脱SessionQ得在应用了Hibernate的J2EE框架中,PO完全可以充当VOQ因此我们下面把PO和VO合ƈQ统UCؓPO?
先来谈谈ActionFormBean和持久层的PO之间的重大区别:
在简单的应用中,ActionFormBean和PO几乎是没有区别,所以很多hq脆是用ActionFormBean来充当POQ于是ActionFormBean从JSP面到Servlet控制层再C务层Q然后穿q持久层Q最后一直映到数据库表。真是一竿子捅到了底Q?
但是在复杂的应用中,ActionFormBean和PO是分ȝQ他们也不可能一栗ActionFormBean是和|页里面的Form表单一一对应的,Form里面有什么元素,Bean里面有什么属性。而PO和数据库表对应,因此如果数据库表不修改,那么PO也不会修改,如果面的流E和数据库表字段对应关系不一_那么你又如何能够使用ActionFormBean来取代PO呢?
比如说吧Q用h册页面要求注册用L基本信息Q因此HTML Form里面包含了基本信息属性,于是你需要一个ActionFormBean来一一对应(注意Q是一一对应)Q每个Bean属性对应一个文本框或者选择框什么的?
而用戯个持久对象呢Q他的属性和ActionFormBean有什么明显不同呢Q他会有一些ActionFormBean所没有的集合属性,比如说用L权限属性,用户的组属性,用户的帖子等{。另外还有可能的是在ActionFormBean里面?个属性,分别是用LFirst Name, Middle Name, Last NameQ而在我的Userq个持久对象中就是一个Name对象属性?
假设我的注册面原来只要你提供First NameQ那么ActionFormBeanp一个属性,后来我要你提供全名,你要改ActionFormBeanQ加两个属性。但是这个时候PO是不应该修改_因ؓ数据库没有改?
那么在一个完整的J2EEpȝ中应该如何进行合理的设计呢?
JSP(View) ---> Action Form Bean (Module) ---> Action(Control)
Action Form Bean是Web层的数据表示Q它和HTML面Form对应Q只要Web面的操作流E发生改变,它就要相应的q行修改Q它不应该也不能被传递到业务层和持久层,否则一旦页面修改,会一直牵q到业务层和持久层的大面U的代码q行修改Q对于Y件的可维护性和可扩展性而言Q是一个灾难,Actiont是他的边界Q到此ؓ止!
Action(Web Control) ---> Business Bean ---> DAO ---> ORM --->DB
而PO则是业务层和持久层的数据表示Q它在业务层和持久层之间q行动Q他不应该也不能被传递到Web层的View中去Q而ActionServlet是他的边界Q到此ؓ止!
然后来看一看整个架构的程Q?
当用户通过览器访问网,提交了一个页面。于是Action拿到了这个FormBeanQ他会把FormBean属性读出来Q然后构造一个PO对象Q再调用业务层的Beanc,完成了注册操作,重定向到成功面。而业务层Bean收到q个PO对象之后Q调用DAO接口ҎQ进行持久对象的持久化操作?
当用h询某个会员的信息的时候,他用全名q行查询Q于是Action得到一个UserNameFormBean包括?个属性,分别是first name, middle name, last nameQ然后Action把UserNameFormBean?个属性读出来Q构造Name对象Q再调用业务BeanQ把Name对象传递给业务BeanQ进行查询?
业务Bean取得Name(注意:Name对象只是User的一个属?对象之后调用DAO接口Q返回一个User的PO对象Q注意这个User不同于在Web层用的UserFormBeanQ他有很多集合属性的。然后业务Bean把User对象q回lAction?
Action拿到User之后Q把User的基本属性取?集合属性如果不需要就免了)Q构造UserFormBeanQ然后把UserFormBean request.setAttribute(...)Q然后重定向到查询结果页面?
查询面拿到request对象里面的ActionFormBeanQ自动调用tag昄之?
ȝQ?
Form Bean是Web层的数据表示Q他不能被传递到业务层;PO是持久层的数据表C,在特定情况下Q例如Hibernate中,他可以取代VO出现在业务层Q但是不POq是VO都必限制在业务层内使用Q最多到达Web层的ControlQ绝不能被扩散到View厅R?
Form Bean和PO之间的数据{化是在Action中进行的?
BTWQ顺便说一句)Q?
JDO1.xq不能像Hibernate功能q样强大QPO不能q持久层,所以必d业务层用VOQ因此必d业务层进行大量的VO和PO的{化操作,相对于Hibernate来说Q编E比较烦琐?
当然了,理论是一回事Q实际操作也不一定非要这样干Q你可以自行取舍Q在实际目中灵zM点,增加一点bad smellQ提高开发效率。只不过在大型项目中最好还是严丝合~,不然的话Q改版的时候会痛苦的很的?