2.7. 资源作为依赖

如果 bean 本身要通过某种动态过程确定并提供资源路径,则 bean 使用 ResourceLoaderResourcePatternResolver接口来加载资源可能是有意义的。例如,考虑加载某种模板,其中所需的特定资源取决于用户的角色。如果资源是静态的,则完全消除ResourceLoader接口(或 ResourcePatternResolver 接口)的使用是有意义的,让 bean 公开其所需的 Resource 属性,并期望将它们注入其中。

然后注入这些属性变得微不足道的是,所有应用程序上下文都注册并使用一个特殊的 JavaBeans PropertyEditor,它可以将String路径转换为Resource对象。例如,以下MyBean类具有Resource 类型的template属性。

package example;

public class MyBean {

    private Resource template;

    public setTemplate(Resource template) {
        this.template = template;
    }

    // ...
}

在 XML 配置文件中,可以使用该资源的简单字符串配置template属性,如以下示例所示:

<bean id="myBean" class="example.MyBean">
    <property name="template" value="some/resource/path/myTemplate.txt"/>
</bean>

请注意,资源路径没有前缀。因此,由于应用程序上下文本身将用作ResourceLoader,因此资源通过 ClassPathResourceFileSystemResourceServletContextResource加载,具体取决于应用程序上下文的确切类型。

如果需要强制使用特定Resource类型,可以使用前缀。以下两个示例展示了如何强制使用 ClassPathResourceUrlResource(后者用于访问文件系统中的文件):

<property name="template" value="classpath:some/resource/path/myTemplate.txt">
<property name="template" value="file:///some/resource/path/myTemplate.txt"/>

如果MyBean类被重构以用于注解驱动的配置,则myTemplate.txt可以将路径存储在名为template.path的键下 - 例如,在 Spring Environment可用的属性文件中(请参阅 环境抽象)。然后可以 使用属性占位符通过注解@Value引用模板路径(请参阅使用@Value)。Spring 会将模板路径的值作为字符串检索,而 指定的PropertyEditor会将字符串转换Resource为要注入MyBean构造函数的对象。以下示例演示了如何实现此目的。

@Component
public class MyBean {

    private final Resource template;

    public MyBean(@Value("${template.path}") Resource template) {
        this.template = template;
    }

    // ...
}

如果我们想支持在类路径中多个位置的同一路径下发现的多个模板——例如,在类路径中的多个 jar 中——我们可以使用特殊classpath*:前缀和通配符将templates.path键定义为 classpath*:/config/templates/*.txt. 如果重新定义如下MyBean类,Spring 会将模板路径模式转换为Resource可以注入MyBean构造函数的对象数组。

@Component
public class MyBean {

    private final Resource[] templates;

    public MyBean(@Value("${templates.path}") Resource[] templates) {
        this.templates = templates;
    }

    // ...
}

最后更新于