??xml version="1.0" encoding="utf-8" standalone="yes"?>
pȝ启动时初始化两部分,一是系l服务,二是pȝqo器,框架定义了系l服务和qo器的接口允许后期Ҏ实际业务实现新的服务和过滤器q|部|到pȝ中?/span>
配置信息如下Q?/span>
<system-config
name="services"> <item
name="condition" value="com.daosheng.service.impl.ConditionManagerImpl"
/> </system-config> |
只配|了一个服务:决策树服务?/span>
配置信息如下Q?/span>
<system-config
name="filters"> <item
name="codefilter"
value="com.daosheng.blackfin.controller.filter.CodeFilter"
/> <item
name="loginfilter" value="com.cqc.filter.LoginFilter"
/> <item
name="logfilter" value="com.cqc.filter.LogFilter" /> </system-config> |
配置xml里面描述了三个过滤器分别是请求代码过滤器、登入过滤器、日志过滤器Q在pȝ初始化这?/span>FilterQ每ơ执行请求时都经q这些过滤器的过滤?/span>
Data Bean 在本框架中有Value
Object?/span>View Object?/span>BO?/span>Java Bean?/span>POJO{多Un份和用途?/span>DataBean是个普通的JavaBeanQ作?/span>POJO通过O/R Mapping来将数据固化到关pL据库或其它存储介质中Q作?/span>Value Bean可以数据在各层之间互相传输Q作?/span>View Object帮助JSP面数据传输ƈ昄出来Q作?/span>BO?/span>service层的Manager们分别具有客观实物类的属性部分和行ؓ部分Q这样分d以服务层更好的分离出来q提供基于接口定义的服务Qƈ更好的Manager及相关类形成独立的组ӞcMSession
Bean,W合façade模式Q?/span>
DataBean贯穿于各个层Q所以当整个目l分配Q务是以层ơ来划分而不是以模块划分工作的时候,DataBean成了各开发h员定义Q务,理解dQ相互沟通的关键部分Q因?/span>DataBean必须能够快速完成ƈ更新。因此本框架采用工具自动扚w生成的办法生?/span>DataBean,Z保证其准性,目l内严o止手工?/span>DataBean?/span>DataBean来自于数据库模型直接生成?/span>XML SchemaQƈ通过Castor生成DataBean。有专门l护数据库模型的人员l一生成Q即便在整个目q程中由于客L原因需求不断变更导致数据库设计不断变更Q?/span>DataBean也能正确的快速的生成出来?/span>
DataBeanq有三个个关键的Ҏ是marshal()?/span>unmarshal()?/span>validate()?/span>Validate()Ҏ提供了对数据q行校验的功能,q样不仅提供了在客户端用javascriptq行校验的功能,q能在服务器q行数据的校验?/span>Marshal?/span>unmarshal两个Ҏ分别可以?/span>DataBean序列化和反序列化?/span>xml文gQ实C?/span>xml文g的快速{换功能。生成的xml可以单独存储Q除了数据库存储的另一中固化方案)Q也可以作ؓ客户端浏览器xmlhttp传输的数据格式,q可以作为提供的web service的传递参敎ͼSOAQ?/span>
权限、事务、日志处理如果杂在业务代码之中会整个代码变得非常复杂而且可读性很差,难以修改重构?/span>
面向对象的分析和设计引入了ѝ抽象和多态等概念Q由此ؓ我们提供了降低Y件复杂性的工具。但是,开发h员在软g设计q程中仍然经怼面对无法用面向对象Y件开发技术轻易解决的问题。这些问题之一是如何处理应用E序中的横切x点(Cross-cutting concernsQ?/span>
1、横切关注点
x点就是设计h员感兴趣的某一概念或区域。例如,在一个订货系l中Q核心关注点可能是订单处理和生Q而系l关注点可能是事务处理和安全理?/span>
横切xҎ影响多个cL模块的关注点Q即未能很好地局部化和模块化的关注点?/span>
横切x点的表现有:
·代码U结?/span>当一个模块或代码D同时管理多个关注点时发生这U情c?/span>
·代码分散?/span>当一个关注点分布在许多模块中q且未能很好地局部化和模块化时发生这U情c?/span>
q些现象会从几个斚w影响软gQ例如,它们会导致Y仉以维护和重用Qƈ且难以编写和理解?/span>
2、关注点的隔?/span>
面向斚w~程试图通过引入?/span>x点的隔离?/span>q一概念来解册些问题。采用这一概念Q可以以一U模块化而且适当局部化的方式实现关注点?/span>AOP解决q个问题的办法是在设计空间中增加额外一l_q且引入了一些构造,q些构造我们能够定义横切x点,它们{U进新的l_q且以模块化方式它们打 包?/span>
声明式的AOP事务配置如下Q?/span>
<bean id="nodeTarget" class="com.daosheng.service.impl.NodeManagerImpl"
singleton="true" lazy-init="default"
autowire="default" dependency-check="default"> <property
name="dao"> <ref
local="nodeDAO" /> </property> </bean> <bean
id="nodeManager" class="com.daosheng.cms.right.RightTransactionProxyFactoryBean" singleton="true"
lazy-init="default" autowire="default" dependency-check="default"> <property
name="transactionManager"> <ref
local="transactionManager" /> </property> <property
name="target"> <ref
local="nodeTarget" /> </property> <property
name="transactionAttributes"> <props>
<prop
key="insert*">
PROPAGATION_REQUIRED,-ApplicationException
</prop>
<prop
key="update*"> PROPAGATION_REQUIRED,-ApplicationException
</prop> </props> </property> </bean> |
其实在注?/span>nodeManager时注册的实际cM是自己开发的NodeManagerImplc而是注册?/span>RightTransactionProxyFactoryBean代理工厂cR在其它c里调用?/span>nodeManagerҎ实际上是先调用的此代理工厂类的加入横切点代码Q事务处理代码)然后在调用的NodeManagerImpl的相应方法,q样实CNodeManagerImplc里不用操心事务问题Q而实际的事务由加入在切点?/span>Advice来完成。其在真正方法执行前启动事务Q执行后提交事务Q?/span>commitQ,如果出现异常则回滚(rollbackQ?/span>
代理工厂cL采用jdk4以上自带的动态代理机制实现的?/span>
框架?/span>AOP中提供了4U处理切入类?/span>:around,before,after,introduction.思义,
1) around是针对具体的某个切入点的Ҏ(比如,现在有个OrderBookҎ,around的切入类型是p个方法的内部调用,是通过java的元
数据,在运行时通过Method.invoke来调?/span>,hq回?/span>,当发生意外的时候会l止.C的一Ҏ,q回?/span>.);
2)before是在Ҏ调用前调?/span>(?/span>OrderBookҎ前调?/span>,但是没有q回?/span>,同时在通常意外情况?/span>,会l运行下一步方?/span>.C的一Ҏ没有q回?/span>);
3)after?/span>before刚好相反,没有什么特别的地方.
4)introduction是一个更加特D的,但功能更加强大的切入cd.比如(你现在有Book对象,Computer对象,q有几十个这U业务对?/span>,现在你希望在每个q样的对象中都加入一个记录最后修改的旉.但是你又不希望对每个c都q行修改,因ؓ太麻烦了,同时更重要的一?/span>,破坏了对象的完整?/span>,说不定你以后又不需要这个时间数据了?/span>.框架AOPZ专门实现q种思想提供了一个切入处?/span>,那就?/span>introduction.introduction可以为动态加入某些方?/span>,q样可以在运行时,强制转换q些对象,q行插入旉数据的动?/span>,更深的内q就?/span>C++虚函C?/span>vtable思想).
下面时序图ؓ事务在整个各层代码协作过E中启动和提交的q程。每?/span>Manager或?/span>DAO实体可能是开发的实际cM可以是代理类?/span>
从逻辑的角度来_checked exceptions?/span>runtime
exception是有不同的用目的的?/span>checked exception用来指示一U调用方能够直接处理的异常情c?/span>runtime exception则用来指CZU调用方本n无法处理或恢复的E序错误?/span>
框架定义了一个异常基c?/span>ApplicationException是属?/span>checked
exceptionscd主要有以下几个功能:
1?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">
异常自底向上抛出l一处理Q减处理代码:传统Q过E式Q方式编E,采用q回参数告诉调用的函数被调用的函数出现错误,所以在调用函数里面要加入很多的if从句来判断各个被调用函数是否正确q回|代码充斥了大量的大括受采用异常机Ӟ发生异常的位|包装成自定义的应用异常然后向上抛出Q上面的各层均不用处理直接抛出到l一异常处理?/span>MainController里面卛_Q由l一的类来处?/span>
2?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">
异常l一~号Q用L到统一的处理信息:每个异常都可以确定编Pq将~号与提CZ息维护在数据库中Q页面只昄l一l护的错误信息,q样׃会让错误信息~程开发h员随手写的不规范而且难以理解的信息,造成用户感觉pȝ难以使用?/span>
3?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">
异常信息记录到错误日志中方便q踪异常位置Q?/span>l一处理E序抓取异常Qƈ异怿息记录日志。调试阶D还可以在控制台信息中打出异常堆Q方便开发h员快速定位异常发生位|?/span>
4?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">
Ҏ获取异常AOP声明式事务控制进行回滚操作:整个开发用声明式的事务,何时回滚取决与应用异常的抛出?/span>
配置如下Q?/span>
<property
name="transactionAttributes"> <props>
<prop
key="insert*">
PROPAGATION_REQUIRED,-ApplicationException
</prop> </props> </property> |
应用异常基类如下图:
其它异常都承于基类ApplicationExceptionQ主要包含错误编号属性(errorNumberQ、异怿息(errorMessageQ、异常跟t?/span>(stackTrace)。以便实Cq功能?/span>
如下图:
1?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">
mvc的主控制servletMain ControllercL供了M控制作用Q所有的h都先映射到此cMQ然后在l一分发到各个部分控制类。由?/span>servlet是支持多U程的,所以性能是可以保证的?/span>
MainControllercȝ承于HttpServletc,主要Ҏ有:
1)
init()ҎQ初始化ҎQ在此方法里面主要初始化一些公q资源、服务,qo器和一些系l基配置参数{。初始化服务q程委托services包中?/span>Service
ManagercL完成Q初始化各种filter?/span>filter包下?/span>Filter Manager来完成?/span>
2)
doPost()?/span>doGet()ҎQ接收各U请求ƈ交给processRequest()Ҏl一处理Q统一?/span>post, get两种h方式?/span>
通过?/span>web.xml中注册和映射Q得各U符合要求的h都直接{发到此控制类上,配置如下Q?/span>
<servlet> <servlet-name>mainCommand</servlet-name> <servlet-class> com.daosheng.blackfin.controller.MainController </servlet-class> <init-param> <param-name>sysconfig</param-name> <param-value>/WEB-INF/blackfin-config.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>mainCommand</servlet-name> <url-pattern>/command/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>mainCommand</servlet-name> <url-pattern>/main/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>mainCommand</servlet-name> <url-pattern>*.cmd</url-pattern> </servlet-mapping> |
q样到hurl?/span>.cmdl尾的或者以/command/?/span>/main/开头的都映到此类上来做统一处理。实Cl一控制功能?/span>
2?/span>filter的接口和理c?/span>
filter包主要包?/span>filter接口?/span>filter的管理类?/span>FilterManagerc负责初始化各注册的filter(开发h员可以自己开发ƈ注册在注册文件中),pȝ控制cL收到各种h先按需要交l过滤类Q?/span>filterQ来q行qoQ然后在由各自业务处理类完成业务处理?/span>
l一qocd以用来完成一些需要每ơ请求都需要判断的逻辑Q比如说d校验Q判断用h否登入过Q如果没有直接蟩转到d面Q还有一个比较关键的qo是CodeFiltercR一般的httph分ؓ两种cdQ一U是普通类型,一U是?/span>multipart cdQ?/span>form?/span>enctype="multipart/form-data"Q可以上传文Ӟ两种cdD在后面服务器端接?/span>form中的参数使用的方法各不相同,multipartcd的用getParameter()Ҏ是没法取出提交上来的参数的,而是要得C?/span>Binary数组自己q行分拆才能得到。导致程序取参数的不一致性,可移植性减弱。所以?/span>CodeFilterҎ?/span>requestq行qoQ将两种情况上传的各U参数都重新setAttribute?/span>request中,q样p够后面?/span>commandcd使用getAttribute()Ҏp取到实际的参数而不需要管是哪U方式提交的了,q且CodeFilter中还可以把一些字W过滤掉Q比如说单引L?/span>
3?/span>h辅助c?/span>
h辅助c(RequestHelperQ主要有两个作用Q一是将requestQ?/span>response和配|参数封装v来然后作?/span>command的参敎ͼ使每?/span>command都能够获取到前台h的各U信息,W二个作用是查找command的各U配|参C息?/span>