Java 使用 Spring 配置初始化默认语言环境和时区

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4416955/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 17:15:04  来源:igfitidea点击:

Initialize default Locale and Timezone with Spring configuration

javaspringtimezonelocale

提问by Tauren

I'm loading application settings such as JDBC connection info from a properties file using PropertyPlaceholderConfigurer. I'd like to also have other settings such as default locale and timezone as properties.

我正在使用PropertyPlaceholderConfigurer. 我还想要其他设置,例如默认语言环境和时区作为属性。

But I'm unsure of the best method to execute Locale.setDefault()and TimeZone.setDefault(). I want them run early in startup and only once. Is there a proper way in Spring to execute some code FIRST, before other code is executed? Any suggestions?

但我不确定执行Locale.setDefault()和的最佳方法TimeZone.setDefault()。我希望它们在启动时尽早运行,并且只运行一次。在执行其他代码之前,Spring 中是否有正确的方法首先执行某些代码?有什么建议?

I know I can specify default values on the command line, but this application will get installed in many places and I want to avoid problems caused by someone forgetting to specify -Duser.timezone=UTCor whatever.

我知道我可以在命令行上指定默认值,但是这个应用程序会安装在很多地方,我想避免因忘记指定-Duser.timezone=UTC或其他原因而导致的问题。

采纳答案by Bozho

I've used a ServletContextListener. In contextInitialized(..)TimeZone.setDefault(..)is called.

我用过一个ServletContextListener。在contextInitialized(..)TimeZone.setDefault(..)被称为。

It won't be taken into account if you rely on the timezone in any constructor or @PostConstruct/ afterPropertiesSet()though.

如果您依赖任何构造函数中的时区或@PostConstruct/afterPropertiesSet()尽管如此,则不会将其考虑在内。

If you need it, take a look at this question

如果你需要它,看看这个问题

回答by kisna

I found Spring loads some of its default beans including other beans before calling the contextInitialized method, so, here is a better approach "draft" that I can think of, let me know if you see any concern:

我发现 Spring 在调用 contextInitialized 方法之前加载了它的一些默认 bean,包括其他 bean,因此,这是我能想到的更好的方法“草稿”,如果您有任何疑问,请告诉我:

public class SystemPropertyDefaultsInitializer 
    implements WebApplicationInitializer{

    private static final Logger logger = Logger
            .getLogger(SystemPropertyDefaultsInitializer.class);

    @Override
    public void onStartup(ServletContext servletContext)
            throws ServletException {
        logger.info("SystemPropertyWebApplicationInitializer onStartup called");

        // can be set runtime before Spring instantiates any beans
        // TimeZone.setDefault(TimeZone.getTimeZone("GMT+00:00"));
        TimeZone.setDefault(TimeZone.getTimeZone("UTC"));

        // cannot override encoding in Spring at runtime as some strings have already been read
        // however, we can assert and ensure right values are loaded here

        // verify system property is set
        Assert.isTrue("UTF-8".equals(System.getProperty("file.encoding")));

        // and actually verify it is being used
        Charset charset = Charset.defaultCharset();
        Assert.isTrue(charset.equals(Charset.forName("UTF-8")));

        // locale
        // set and verify language

    }

}

回答by richard

How about standalone spring boot application? The java application looks like:

独立的 Spring Boot 应用程序怎么样?Java 应用程序如下所示:

@SpringBootApplication
@EnableScheduling
@EnableConfigurationProperties(TaskProperty.class)
public class JobApplication {

/*  @Autowired
    private TaskProperty taskProperty;
*/  
    public static void main(String[] args) {
        SpringApplication.run(JobApplication.class, args);
    }
} 

回答by M. Justin

It may make sense to ensure that these are set before any beans are processed or initialized, as any beans created before this code is run could end up using the previous system default values. If you are using Spring Boot, you could do this in the mainmethod before even initializing Spring:

确保在处理或初始化任何 bean 之前设置这些可能是有意义的,因为在运行此代码之前创建的任何 bean 最终可能会使用以前的系统默认值。如果您使用的是 Spring Boot,您甚至可以在main初始化 Spring 之前在方法中执行此操作:

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        Locale.setDefault(Locale.US);
        TimeZone.setDefault(TimeZone.getTimeZone("America/New_York"));

        SpringApplication.run(Application.class, args);
    }
}

If this needs to be run as part of a context that doesn't call the main method, e.g. in a JUnit integration test, you would need to make sure that it's called:

如果这需要作为不调用 main 方法的上下文的一部分运行,例如在 JUnit 集成测试中,您需要确保它被调用:

@SpringBootTest
public class ApplicationTest {
    @BeforeClass
    public static void initializeLocaleAndTimeZone() {
        // These could be moved into a separate static method in
        // Application.java, to be called in both locations
        Locale.setDefault(Locale.US);
        TimeZone.setDefault(TimeZone.getTimeZone("America/New_York"));
    }

    @Test
    public void applicationStartsUpSuccessfully() {
    }
}