读书人

Spring圆满设计:Resource接口与策略模

发布时间: 2012-12-19 14:13:15 作者: rapoo

Spring完美设计:Resource接口与策略模式

不管是资源(Resource),还是资源加载器(ResourceLoader),Spring都把它定义成了接口的形式,而不是类的形式。这样降低了与具体的实现类之间的耦合,更具灵活性与易扩展性。它们的关系图如下:

?


Spring圆满设计:Resource接口与策略模式
?

且看ResourceLoader的getResource(String location)方法的声明:

/** * Return a Resource handle for the specified resource. * The handle should always be a reusable resource descriptor, * allowing for multiple {@link Resource#getInputStream()} calls. * <p><ul> * <li>Must support fully qualified URLs, e.g. "file:C:/test.dat". * <li>Must support classpath pseudo-URLs, e.g. "classpath:test.dat". * <li>Should support relative file paths, e.g. "WEB-INF/test.dat". * (This will be implementation-specific, typically provided by an * ApplicationContext implementation.) * </ul> * <p>Note that a Resource handle does not imply an existing resource; * you need to invoke {@link Resource#exists} to check for existence. * @param location the resource location * @return a corresponding Resource handle * @see #CLASSPATH_URL_PREFIX * @see org.springframework.core.io.Resource#exists * @see org.springframework.core.io.Resource#getInputStream */Resource getResource(String location);

接口的声明,要求location的格式能满足多形式,也就是要支持多种类型的Resource。上面的类关系图中,我们就可看出有两种Resource,分别是UrlResource和ClasspathResource,前者是加载URL指定的资源,后者是加载类路径中的资源。

我们来看看Spring实现类DefaultResourceLoader中是如何用一个接口方法加载两种资源的:

?

public Resource getResource(String location) {Assert.notNull(location, "Location must not be null");if (location.startsWith(CLASSPATH_URL_PREFIX)) {return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());}else {try {// Try to parse the location as a URL...URL url = new URL(location);return new UrlResource(url);}catch (MalformedURLException ex) {// No URL -> resolve as resource path.return getResourceByPath(location);}}}

?

getResource()方法的传入参数,就作为一种策略,要求实现类去判断这种策略的类型,并返回相应的Resource。在这里,Spring是通过try-catch的形式,先判断是否是UrlResource,若不是,则把它当作是ClassPathContextResource来处理。在策略的种类多时,使用if-else判断或switch判断可能更好一点。

?

此外,我们使用策略模式,常常会定义一个策略接口,策略接口有不同的实现类,分别代表不同的策略。如下图:


Spring圆满设计:Resource接口与策略模式
?

在使用策略的时候,将策略接口作为形参,而可传进各种具体的策略实现类对象作为实参,在doSomething()方法中,根据策略的类型,来决定要作出什么样的处理。

?

读书人网 >编程

热点推荐