SpringMVC视图文件View*.xml模块化配置改造

最近基于SpringMVC的视图配置文件进行了一些小的改写,原因是为了实现在同一平台下实现不同项目的视图文件view*.xml的模块化配置。

来看一段常规程序及其配置实例:

controller:

public ModelAndView delete(@RequestParam("rowid") Long rowid)throws ServletException, IOException {	
	return new ModelAndView("sojoJsonView",AppUtil.delRecord(rowid,manager));
}

views.xml配置:

<bean name="sojoJsonView" class="org.springframework.web.servlet.view.json.JsonView">
	<property name="encoding" value="UTF-8"/>
	<property name="contentType" value="application/json"/>
	<property name="jsonWriter" ref="sojoJsonWriter"/>
    	<property name="jsonErrors">
	    	<list>
	        	<ref bean="statusError" />
	        	<ref bean="modelflagError" />
	        </list>
        </property>
</bean>

xxx-servlet.xml配置:

<bean id="viewResolver" class="org.springframework.web.servlet.view.XmlViewResolver"/>

我们可以看到,在controller的方法里面返回一个名叫"sojoJsonView"的模型和视图对象,那么在返回客户端之前的视图类里面,SpringMVC的框架程序就会去按照我们传入的模型和视图对象名称去解析了。那么为什么视图类就知道到views.xml里面去找相应的配置视图bean呢?为什么只能写一个views.xml配置文件,而且名称只能写成views.xml。带着这些问题,我们接下来看一段源码:

public class XmlViewResolver extends AbstractCachingViewResolver implements Ordered, InitializingBean, DisposableBean
{
	public static final String DEFAULT_LOCATION = "/WEB-INF/views.xml";
  	...
  	private Resource location;
  	...

  	protected synchronized BeanFactory initFactory()throws BeansException{
    		...

    		Resource actualLocation = this.location;
    		if (actualLocation == null) {
      			actualLocation = getApplicationContext().getResource("/WEB-INF/views.xml");
    		}
		...
  	}
	...
}

注:“...”表示省略。

从引用的源码中知道:在初始化bean工厂的时候,将views.xml文件写死在程序里了,这就是在引用SpringMVC框架的时候,为什么视图类就知道到views.xml里面去找相应的配置视图bean,为什么只能写一个views.xml配置文件,而且名称只能写成views.xml。在这里就会有一个问题产生了,就是在不同的项目里面,软件研发人员希望每个项目有独立的配置文件,这样既可以实现模块化配置,也更容易保护框架本身的安全性配置。

那么如何来实现呢?看看思路:

就是能否利用getApplicationContext()方法返回的实体对象,调用一个本身的返回数组的方法,也许可以实现。下面我们需要找一些已经实现的理论依据来支撑这种想法:

从源码:

actualLocation = getApplicationContext().getResource("/WEB-INF/views.xml");

中可以看到,我们需要可以找到接口类:ApplicationContext。

下面看ApplicationContext接口类源码:

public abstract interface ApplicationContext extends ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver
{
  public abstract String getId();

  public abstract String getDisplayName();

  public abstract long getStartupDate();

  public abstract ApplicationContext getParent();

  public abstract AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
}

在接口ApplicationContext中,实现了ResourcePatternResolver接口类。

下面看ResourcePatternResolver接口类源码:

public abstract interface ResourcePatternResolver extends ResourceLoader {

  public static final String CLASSPATH_ALL_URL_PREFIX = "classpath*:";

  public abstract Resource[] getResources(String paramString) throws IOException;
}

在接口ResourcePatternResolver里面定义了一个资源类的返回数据的方法getResources(String paramString)。

从上面的连续接口实现中,我们可以知道,ApplicationContext接口类可以返回一个数组对象,即:getApplicationContext().getResources(String paramString);

这样就为我们的视图文件模块化实现找到了可行性的方法,看一段改造后的源码:

public class XmlViewResolver extends AbstractCachingViewResolver implements Ordered, InitializingBean, DisposableBean {

	private final static String VIEW_FILE="/WEB-INF/view*.xml"; 
	...
	private Resource[] location;
	...
	protected synchronized BeanFactory initFactory() throws BeansException {
	    ...
	    Resource[] actualLocation = this.location;
	    if (actualLocation == null) {
	    	try {
	    		actualLocation = getApplicationContext().getResources(VIEW_FILE);
	    	} catch (IllegalStateException e) {
	    	} catch (IOException e) {
	    	}
	    }
	    ...
	}
	...
}

从改造后的源码中,我们就可以实现不同项目的视图配置文件的模块化配置了,比如:view-a.xml、view-b.xml。同时XXX-servlet.xml的配置如下:

<bean id="viewResolver" class="com.sunline.framework.util.XmlViewResolver"/>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值