9D4.Auto Timezone and I18n
9D4.Auto Timezone and I18n
The careful handling of language and timezones is an important feature that distinguishes WingsBoot from other frameworks.
- time - can system-level, thread-level tweak clock
- timezone - by annotation or type , to auto convert Dto/pojo
- language - strong type MessageCode, EnumCode constants with auto conversion
Tweak Clock and Timeline
There are typically two types of clocks within a system, the system clock, which requires a linear timeline, and the business clock, which may require traversal. The system clock may also need to be tuned to a different timeline, especially during test, deduce and replay.
- mirana's
ThreadNow
andSlideDate
basic version to tweak system clock - slardar's
Now
advanced version to tweak system clock, also the user timeline
So, when writing a program, if you need to tweak the timeline (all business code is recommended)
Now.xxx()
instead ofXxxx.now()
if dep on slardarThreadNow.xxx()
instead, if not dep on slardar, but on mirana dependency
It is important to note whether the business thread model supports ThreadLocal's Inheritable.
- ThreadNow use ThreadLocal by default
- Now uses TransmittableThreadLocal by default to override the default value of ThreadNow
The jmh Benchmark on ThreadNow.xxx() and Xxx.now() is basically the same
Benchmark Mode Cnt Score Error Units
NowMain.now thrpt 6 11942.923 ± 368.430 ops/ms
NowMain.sys thrpt 6 12910.824 ± 226.997 ops/ms
I18n of Time and Text
WingsBoot's automatic conversion relies on two Contexts to get the ZoneId and Locale
- spring's
LocaleContextHolder
, used in the web layer - slardar's
TerminalContext
, which is recommended, especially in the Service layer
Automatic conversion occurs in SpringMvc's Request and Response, respectively
- Jackson's @RequestBody, @ResponseBody
- Spring's Data Binding, such as @Param
Manual conversions are handled by AutoDtoHelper
, such as Excel output, but avoid automatic conversions.
- Only works for annotation fields by default, while auto-conversion can be handled by type
- Only non-final and transient fields with getters are supported by default
The types and configuration items involved in auto-conversion are
- LocaleDateTime - wings.slardar.datetime.datetime.auto=false
- ZonedDateTime - wings.slardar.datetime.zoned.auto=false
- OffsetDateTime - wings.slardar.datetime.offset.auto=true
- I18nString - without config, auto convert
The annotations involved in the automatic and manual conversions are
- AutoDtoAble - marks the container class field (manual conversion only)
- AutoI18nString - marks String or I18nString type
- AutoTimeZone - marks the DateTime of Local/Zoned/Offset
Context Rule and Pitfall
All Context implicitly passing variables, that have side effects, are considered anti-patterns and should follow the rules and be used with caution. Avoid using Functions with sideEffects in Wings, but Context does provide convenience and works very well.
ThreadLocal is often used to implement Context, and ThreadLocal must be set and removed correctly. Either in try{set}finally{remove}
or some mechanism to ensure there are no misreads or memory leaks.
Wings uses Transmittable-ThreadLocal by default, and use TransmittableThreadLocal whenever possible, wrap Spring's Executor as TtlExecutors to ensure correct Context passing.
In scenarios with complex thread models, be sure to follow the principles and concerns of Transmittable-ThreadLocal to correctly handle the Context and ensure proper business code.
- TerminalContext - handled by slardar's TerminalInterceptor
- Now - As business requirement, need to
try{adjust()}finally{remove()}
by yourself