自定义 Spring Boot 启动器:如何向 MessageSource 贡献 i18n 消息?
我正在编写一个自定义 Spring Boot 启动器,其他开发人员将放入他们的应用程序,这个启动器包含开箱即用的控制器和 UI 屏幕.
I'm writing a custom Spring Boot starter that other developers will drop into their applications, and this starter contains out-of-the-box controllers and UI screens.
这些 UI 屏幕是国际化的,并且 i18n 键/值位于一个包文件中:com/foo/wherever/i18n.properties
.
These UI screens are internationalized and the i18n keys/values are in a package file: com/foo/wherever/i18n.properties
.
我想确保当我的启动器在启动时加载时,这些 i18n.properties 在应用程序的 MessageSource
中自动可用,以便我的 UI 页面正常工作(通过普通 Spring Controller + ViewResolver +查看实现)应用开发者无需自己指定此文件.
I want to ensure that when my starter is loaded at startup, that these i18n.properties are available in the application's MessageSource
automatically so that my UI pages work (rendered via normal Spring Controller + ViewResolver + View implementations) without the app developer having to specify this file themselves.
换句话说,他们应该能够将我的启动器添加到他们的运行时类路径中,并且一切都正常工作"而无需配置任何东西.
In other words, they should be able to add my starter to their runtime classpath and everything 'just works' without the need to configure anything.
现在,我发现app开发者可以自己创建src/main/resources/messages.properties
文件手动配置application.properties
:
Now, I have discovered that the app developer can create their own src/main/resources/messages.properties
file and manually configure the additional messages file in application.properties
:
spring.messages.basename = messages, com.foo.wherever.i18n
这会奏效.
但是,这需要以下两个条件:
However, this requires both of the following:
- 他们必须手动配置
spring.messages.basename
属性 - 这不是自动的.和 - 他们的应用程序类路径中必须有自己的
messages.properties
文件.如果messages.properties
文件不存在,则spring.messages.basename
甚至不起作用.即使他们不关心 i18n,这仍然是必需的 - 不可取.
- They must manually configure the
spring.messages.basename
property - it's not automatic. and - They must have their own
messages.properties
file in their application classpath. If amessages.properties
file does not exist,spring.messages.basename
doesn't even work. Even if they don't care about i18n, this is still required - not desirable.
我想我可以将我的 i18n.properties 文件移动到 starter .jar 中的 classpath:/messages.properties 文件,但这似乎不是一个好的解决方案:如果应用程序开发有自己的 messages.properties 文件,只会读取其中一个,导致消息值丢失.
I suppose I could move my i18n.properties file to a classpath:/messages.properties file in the starter .jar, but that doesn't seem like a good solution: if the app dev has their own messages.properties file only one of them would be read, resulting in missing message values.
好像 Spring Boot MessageSourceAutoConfiguration 应该有一个 CompositeMessageSource
的概念,它迭代一个或多个 MessageSource
实例,这些实例是在 Spring ApplicationContext 中可用(和 Order
ed)并且 that 由 DispatcherServlet 使用.这将允许任何初学者通过在其自动配置中声明一个 MessageSource
来为可用消息做出贡献
It seems as if Spring Boot MessageSourceAutoConfiguration should have a concept of a CompositeMessageSource
that iterates over one or more MessageSource
instances that are available (and Order
ed) in the Spring ApplicationContext and that is used by the DispatcherServlet. This would allow any starter to contribute to the available messages just by declaring a MessageSource
in their auto config
可以按照我的要求去做吗?对于应用开发者来说,最不干涉"的解决方案是什么?
Is it possible to do what I ask? What is the most 'hands off' solution for the app developer?
推荐答案
可能有点远,但你可以尝试使用 BeanFactoryPostProcessor.
Maybe it is long shot but you can try to use BeanFactoryPostProcessor.
思路如下:
将messageSource"bean 从应用程序上下文中取出.请注意,如果例如,它可能但不一定是弹簧靴的.开发者希望使用自己的实现,不要使用 spring boot 自动配置.
Take "messageSource" bean out of the application context. Note that it might but does not have to be a spring boot's one if e.g. developer wants to use its own implementation and don't use spring boot autoconfiguration.
将其替换为您自己的实现,该实现尝试解析您的密钥"并将其余的委托给原始消息源.反之亦然,如果您希望开发人员能够覆盖您的翻译(如果原始消息源没有为未知键引发异常,则可能会出现问题).
Replace it with your own implementation that tries to resolve "your keys" and the rest delegate to original message source. Or vice versa if you want to make possible to override your translations by developer (there can be problems if original message source does not throw exception for unknown keys).
但可能有更好的方法来做到这一点.
But there might be a better way to do that.
相关文章