我正在使用PropertyPlaceholderConfigurer从属性文件加载应用程序设置,例如JDBC连接信息。我还想将其他设置(如默认语言环境和时区)作为属性。
但我不确定执行Locale.setDefault()
和TimeZone.setDefault()
的最佳方法。我希望他们在启动时早点运行一次。在其他代码执行之前,Spring是否有正确的方法执行某些代码?有什么建议吗?
我知道我可以在命令行上指定默认值,但是这个应用程序将安装在很多地方,我想避免因忘记指定-Duser.timezone = UTC或其他原因而引起的问题。
答案 0 :(得分:11)
我发现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
}
}
答案 1 :(得分:6)
我使用了ServletContextListener
。在contextInitialized(..)
TimeZone.setDefault(..)
中调用。
如果您依赖任何构造函数或@PostConstruct
/ afterPropertiesSet()
中的时区,则不会将其考虑在内。
如果您需要,请查看this question
答案 2 :(得分:1)
确保在处理或初始化任何Bean之前设置它们是有道理的,因为在运行此代码之前创建的任何Bean最终都可能使用以前的系统默认值。如果您使用的是Spring Boot,则可以在初始化Spring之前通过main
方法执行此操作:
@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);
}
}
如果需要将其作为不调用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() {
}
}
答案 3 :(得分:-6)
独立弹簧启动应用程序如何? java应用程序看起来像:
@SpringBootApplication
@EnableScheduling
@EnableConfigurationProperties(TaskProperty.class)
public class JobApplication {
/* @Autowired
private TaskProperty taskProperty;
*/
public static void main(String[] args) {
SpringApplication.run(JobApplication.class, args);
}
}