ban*_*rCZ 16 java plugins spring classpath
我正在使用Spring框架为基于Web的应用程序设计插件系统.插件是类路径上的jar.所以我能够得到像jsp这样的资源,见下文
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource[] pages = resolver.getResources("classpath*:jsp/*jsp");
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.但我的messageSource有问题.在我看来,ReloadableResourceBundleMessageSource #setBasename不支持通过"classpath*:"的多个类路径.如果我只使用"classpath:",我只从一个插件获取messageSource.
有没有人知道如何从所有插件注册messageSources?是否存在MessageSource的这种实现?
aja*_*sti 17
随着@ seralex-vi basenames/WEB-INF/messages的解决方案无效.
我在类ReloadableResourceBundleMessageSource上覆盖方法refreshProperties,它执行两种类型的基本名称(classpath*:和/ WEB-INF /)
public class SmReloadableResourceBundleMessageSource extends ReloadableResourceBundleMessageSource {
private static final String PROPERTIES_SUFFIX = ".properties";
private PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
@Override
protected PropertiesHolder refreshProperties(String filename, PropertiesHolder propHolder) {
if (filename.startsWith(PathMatchingResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX)) {
return refreshClassPathProperties(filename, propHolder);
} else {
return super.refreshProperties(filename, propHolder);
}
}
private PropertiesHolder refreshClassPathProperties(String filename, PropertiesHolder propHolder) {
Properties properties = new Properties();
long lastModified = -1;
try {
Resource[] resources = resolver.getResources(filename + PROPERTIES_SUFFIX);
for (Resource resource : resources) {
String sourcePath = resource.getURI().toString().replace(PROPERTIES_SUFFIX, "");
PropertiesHolder holder = super.refreshProperties(sourcePath, propHolder);
properties.putAll(holder.getProperties());
if (lastModified < resource.lastModified())
lastModified = resource.lastModified();
}
} catch (IOException ignored) {
}
return new PropertiesHolder(properties, lastModified);
}
Run Code Online (Sandbox Code Playgroud)
在spring-context.xml上,您必须具有classpath*:前缀
<bean id="messageSource" class="SmReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<value>/WEB-INF/i18n/enums</value>
<value>/WEB-INF/i18n/messages</value>
<value>classpath*:/META-INF/messages-common</value>
<value>classpath*:/META-INF/enums</value>
</list>
</property>
</bean>
Run Code Online (Sandbox Code Playgroud)
您可以执行类似于下面的操作 - 实质上明确指定每个相关的基本名称.
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<value>classpath:com/your/package/source1</value>
<value>classpath:com/your/second/package/source2</value>
<value>classpath:com/your/third/package/source3/value>
<value>classpath:com/your/fourth/package/source4</value>
</list>
</property>
</bean>
Run Code Online (Sandbox Code Playgroud)
这里的问题不是多个类路径或类加载器,而是代码将为给定路径尝试和加载多少资源.
该classpath*
语法是一个弹簧机构,一个允许的代码来加载多个资源对于给定的路径.非常便利.但是,ResourceBundleMessageSource
使用标准java.util.ResourceBundle
来加载资源,这是一个更简单的dumber机制,它将加载给定路径的第一个资源,并忽略其他所有内容.
我真的没有一个简单的解决方案.我认为你将不得不放弃ResourceBundleMessageSource
并编写一个自定义实现MessageSource
(很可能通过子类化AbstractMessageSource
),它PathMatchingResourcePatternResolver
用于定位各种资源并通过MessageSource
接口公开它们.ResourceBundle
不会有太大帮助.
归档时间: |
|
查看次数: |
24305 次 |
最近记录: |