我正在编写一个自定义的 Spring 启动启动器,其他开发人员将放入他们的应用程序中,这个启动器包含开箱即用的控制器和 UI 屏幕。
这些UI屏幕是国际化的,i18n键/值在一个包文件中:< code > com/foo/where/i18n . properties 。
我想确保当我的starter在启动时加载时,这些i18n.properties在应用程序的< code>MessageSource中自动可用,这样我的UI页面就可以工作(通过普通的Spring Controller ViewResolver视图实现呈现)而无需应用程序开发人员自己指定这个文件。
换句话说,他们应该能够将我的启动器添加到他们的运行时类路径中,并且一切都“正常工作”,而无需配置任何内容。
现在,我发现应用程序html" target="_blank">开发人员可以创建自己的< code > src/main/resources/messages . properties 文件,并在< code > application . properties 中手动配置附加消息文件:
spring.messages.basename = messages, com.foo.wherever.i18n
这将起作用。
但是,这需要满足以下两项条件:
我想我可以移动我的i18n。属性文件转换为类路径:/messages。jar中的properties文件,但这似乎不是一个好的解决方案:如果应用程序开发人员有自己的消息。属性文件只读取其中一个属性,从而丢失消息值。
看起来Spring Boot MessageSourceAutoCon人和应该有一个CompositeMessageSource
的概念,它迭代一个或多个MessageSource
实例,这些实例在Spring Application ationContext中可用(和令
ed),并由DispatcherServlet使用。这将允许任何启动器通过在其自动配置中声明MessageSource
来贡献可用消息
有可能做到我要求的吗?对应用程序开发人员来说,最“不干涉”的解决方案是什么?
我意识到这是一个老掉牙的问题,但前几天我遇到了同样的问题,并写了一篇关于我决定如何解决这个问题的博文。我想我应该在这里分享它,因为我从这个线程中得到了一些解决方案的灵感。
简而言之,它采用了 sodik 拦截 MessageSource bean 创建的想法,但我使用的是 BeanPostProcessor,而不是使用 BeanFactoryPostProcessor
,而不是替换应用程序上下文中的原始
MessageSource
,我只是添加我自己的作为其父级:
@Bean
BeanPostProcessor messageSourceCustomExtender() {
return new BeanPostProcessor() {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof HierarchicalMessageSource && beanName.equals("messageSource")) {
ResourceBundleMessageSource parent = new ResourceBundleMessageSource();
parent.setBasename("custom");
((HierarchicalMessageSource) bean).setParentMessageSource(parent);
}
return bean;
}
};
}
你可以阅读完整的博客文章,其中我解释了一些关于我的解决方案的警告:http://www.thomaskasene.com/2016/08/20/custom-spring-boot-starter-messagesource/
经过一些修补,我意识到使用< code > BeanFactoryPostProcessor 是错误的,因为它将导致过早地创建原始的< code>MessageSource bean,并忽略应用程序属性(最重要的是< code > spring . messages . basename )。这意味着应用程序将无法配置这些属性。请参见下面的BeanFactoryPostProcessor文档摘录。
BeanFactoryPostProcessor可以与bean定义交互并修改bean定义,但不能修改bean实例。这样做可能会导致过早的bean实例化,违反容器并导致意想不到的副作用。如果需要bean实例交互,请考虑实现BeanPostProcessor。
我已经更新了上面的示例以改用 BeanPostProcessor
,这会更改 Bean 实例而不是 Bean 定义。
也许这是一个长远的目标,但你可以尝试使用BeanFactoryPostProcessor。
想法如下:
> < li>
将“message source”bean从应用程序上下文中取出。请注意,如果开发人员想要使用自己的实现,并且不使用spring boot自动配置,那么它可能是但不是必须是spring boot的。
将其替换为您自己的实现,该实现尝试解析“您的键”,其余委托给原始消息源。如果您想让开发人员覆盖您的翻译,反之亦然(如果原始消息源不为未知键抛出异常,可能会出现问题)。
但是也许有更好的方法。
我按以下方式设置了它。我目前只支持en_US但它被设置为使用国际化(i18n)处理任意数量的语言。
在此处查看代码要点:github要点上的代码
将这些beans添加到您的Application.java中,以设置您的默认语言环境并配置您的消息属性的位置
服务将从会话中获取默认区域设置,然后从您的 prop 获取消息文本
注入消息svc,然后传递id以从props文件中获取值
转到/资源:
您可以在此处查看有关此主题的更完整的文章:Spring Boot国际化使用消息属性
在此处查看代码要点:github要点上的代码
问题内容: 我正在编写一个自定义的Spring Boot入门程序,其他开发人员将其放入他们的应用程序中,并且该入门程序包含开箱即用的控制器和UI屏幕。 这些UI屏幕已经国际化,并且i18n键/值在打包文件中:。 我想确保在启动时加载启动程序时,这些i18n.properties可以自动在应用程序中使用,以便我的UI页面可以工作(通过常规Spring Controller + ViewResolve
文档更新 如果修改了组件代码,需要在组件目录的metas.yml加上changes,直接使用next作为版本号(如果已经存在该版本号,则直接添加变更条目即可)。 中括号内为变更类型,可选值 fix enhance feature change 比如: changes: next: en: - '[fix] fix *** bug #issueId' - '[fe
在 Github 上 Fork 项目到自己的仓库。 将 fork 后的项目拉到本地: git clone https://github.com/<user-name>/kubernetes-handbook。 新建一个分支,并添加或编辑内容:git checkout -b new-branch。 提交并推送到 github:git commit -am "comments"; git push。
我们非常欢迎您的贡献和加入,无论是微不足道的清理或大的新功能。我们希望为每个编程语言提供高质量、有良好文档的代码。 这也不是代码是唯一有贡献项目的方式。我们非常重视文档、与其他项目的集成,并欣然接受这些方面的改进。 联系我们 Nacos Gitter-https://gitter.im/alibaba/nacos Nacos 微博-https://weibo.com/u/6574374908 Na
在Github上Fork到自己的仓库 将fork后的项目拉到本地: git clone https://github.com/<user-name>/sdn-handbook 新建一个分支,并添加或编辑内容:git checkout -b new-branch 提交并推送到github:git commit -am "comments"; git push 在Github上提交Pull Reque
我正在开发一个Spring启动自定义启动器,其中pom包含一些依赖项(其他启动器、库),并且这个启动器执行一些关于jwt过滤的配置,以允许过滤器处于安全水位。问题是当我在另一个项目(starter-消费者)中添加我的自定义启动器作为pom依赖项时,它似乎检测到我要导入的类,但IntelliJ什么也没做。 也许我没有正确打包启动器,或者至少我在里面编码的类。启动器在pom中包含的其他依赖项被成功添加