我们在上面讨论过了怎么实现MultiMethodControllerUrlHandlerMapping,要实现为具体的代码,我们可以通过扩展org.springframework.web.servlet.handler.AbstractUrlHandlerMapping。AbstractUrlHandlerMapping扩展了org.springframework.web.context.support.WebApplicationObjectSupport。WebApplicationObjectSupport可以获得当前WebApplicationContext。
1. 重写initApplicationContext方法,在context中查找所有MultiActionController类型的bean,把MultiActionController的urlMethodmappings属性的key值为key值,MultiActionController实例为键值的键值对添加到一个urlMap中。
public class MultiMethodControllerUrlHandlerMapping extends AbstractUrlHandlerMapping {
private Map urlMap = new HashMap();
public void initApplicationContext() throws BeansException {
initialUrlMap();
}
protected void initialUrlMap()throws BeansException {
// 找查所有MultiMethodController类型和子类型的bean到一个map中,bean Name为key值 ,bean实例为value值
Map matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(
getWebApplicationContext(),
MultiMethodController. class , true , false );
List controllers = null ;
if ( ! matchingBeans.isEmpty()) {
controllers = new ArrayList(matchingBeans.values());
for ( int i = 0 ; controllers != null && i < controllers.size();i ++ ) {
MultiMethodController controller = (MultiMethodController)controllers. get (i);
Properties urlPros = controller.getUrlMethodmappings();
Iterator itr = urlPros.keySet().iterator();
for (;itr.hasNext();) {
String url = (String)itr.next();
urlMap.put(url,controller);
}
}
}
}
2. 遍历urlMap,调用AbstractUrlHandlerMapping的registerHandler(String urlPath, Object handler)方法,依次将url与对应的handler注册到AbstractUrlHandlerMapping的handlerMap中。
protected
void
registerUrlMap()throws BeansException
{
if
(
this
.urlMap.isEmpty())
{
logger.info(
"
Neither 'urlMap' nor 'mappings' set on MultiMethodControllerUrlHandlerMapping
"
);
}
else
{
Iterator itr
=
this
.urlMap.keySet().iterator();
while
(itr.hasNext())
{
String url
=
(String) itr.next();
Object handler
=
this
.urlMap.
get
(url);
//
prepend with slash if it's not present
if
(
!
url.startsWith(
"
/
"
))
{
url
=
"
/
"
+
url;
}
//
父类方法
registerHandler(url, handler);
}
}
}
然后在initApplicationContext方法中调用registerUrlMap方法
public
void
initApplicationContext() throws BeansException
{
initialUrlMap();
registerUrlMap();
}
3. 使用MultiMethodControllerUrlHandlerMapping
使用MultiMethodControllerUrlHandlerMapping,只需要在ApplicationContext中,定义成一个bean就可以了。
id
=
"
multiMethodControllerUrlHandlerMapping
"
class
=
"
com.prs.application.ehld.web.handler.MultiMethodControllerUrlHandlerMapping
"
>
<
property name
=
"
order
"
>
<
value
>
3
</
value
>
</
property
>
</
bean
>
注意:在一个context如果定义多个HandlerMapping,需要为每一个HandlerMapping指定order属性。
你只需要在在context 中定义MultiMethodControllerUrlHandlerMapping,在使用MultiActionController时,只需要配置urlMethodmappings属性就可以了。当删除或增加一个MultiActionController的bean时,无需要连带配置任何HandlerMapping. 简化了bean的配置。使得MultiActionControler的bean配置只关心自身的属性配置,而无需要去关心看起来与自身无关的HandlerMapping的配置。使得整个配置更合乎人们正常的思维逻辑,减少配置的复杂性。
6.设计讨论
在这里我们将对以Spring为基础进行项目架构设计进行一些讨论.
1. MultiActionController还是AbstractController与SimpleFormController组合
在使用Spring MVC时,SimpleFormController用于表单编辑和提交;而复杂的功能则通过扩展AbstractcController完成。这就是所谓的AbstractController与SimpleFormController组合。以AbstractController与SimpleFormController的结合来完成表示层逻辑。
Spring MVC虽然也提供了MultiActionController,但是它似乎天生就有点蹩脚。对数据绑定支持不是很好,在用于表单编辑和提交时不像SimpleFormController那么强大。其实通过对MultiActionController的扩展和增强,完成可以实现与SimpleFormController同样的功能,比如数据校验等,并且还比SimpleFormController具有更多的灵活性。
在OO技术中,有一个重要的原则:低耦合,高内聚;我们应该按职责来设计对象。按对象应该具有的职责来给对象设计相应的方法。如果把一个对象本来该具有的职责分散到不同类中去完成,那么这个些类是违反“低耦合,高内聚”原则的。一个类不是高内聚的,就不便于维护和扩展,造成大量重复代码的产生。同样把一组相关的功能分散到多个Controller去实现,是违反“低耦合,高内聚”原则的,可以就会产生大量的重复代码。比如参数获取,数据校验等。如果使用MultiActionController,把相关的功能由一个Controller的不同方法实现,集中在一个Controller类中处理,就使得这个Controller类是具有“高内聚”性的。所以,在项目应用中,相关的功能应该由一个MultiActionController的不同方法去实现。这样就便于代码的维护,提高代码的重用,减少bean配置,降低项目的复杂度。
2. 灵活性与简易化
Spring作为一个轻量级的j2ee基础框架,使用是非常灵活的。特别是可以通过xml文件来灵活的配置对象之间的依赖。但是,以Spring作为框架的项目,bean的配置太多,反而增加了项目的复杂度。在开发过程中,应该把主要精力花在关注业务逻辑的实现上面,而不应该花在配置上面。灵活度越大也就导致了复杂度越高。当然,Spring是一个通用框架,应该具有这样的灵活性,才便于扩展,以满足各种应用需要。
在具体的项目中,就应该使架构使用起来简单,易用。特别是以Spring作为基础的架构中,应该通过设计降低配置的复杂度,尽可能的减少bean的配置和使配置简单化。
一个bean属性发生变化,不应该产生连带关系,使得其它bean也需要修改配置。这是不利于团队开发的。在团队开发中,开发人员应该只关心业务对象的bean配置。
像HandlerMapping这些属于框架基础bean配置一旦定义后就应该具有稳定性。不要因为业务对象bean的改变而需要开发人员随之进行修改。
3. 增强的MultiActionController与MultiMethodControllerUrlHandlerMapping
通过扩展MultiActionController,使得它得到增强,能够实现SimpleFormController的功能,同时使得配置更加直观和简易。
只需要定义一个MultiMethodControllerUrlHandlerMapping,使得开发人员只需要关注相关MultiActionController的配置,而无需去再关注和修改HandlerMapping的配置。
通过MultiMethodControllerUrlHandlerMapping 与增强的MultiActionController结合,更易于运用OO技术设计高内聚的 Controller类,减化bean的配置。让开发人员把精力花在系统的业务逻辑的实现上,而不会去过度关心bean的配置