5.实现MultiMethodControllerUrlHandlerMapping
我们在上面讨论过了怎么实现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的配置