Objective
For spring boot, there are a lot of high-quality series of tutorials online, I will no longer swim (actually worry about no one else to write good, haha ha!) )。 But still want to rub spring boot heat, even if not consider microservices, spring boot has a lot of advantages, such as automated configuration, series starters simplifies maven dependency management. This series is mainly to integrate some of the functions involved in the work with the Spring boot integration (work is useless to spring-boot).
Maven-ssm-web in the content will be integrated into the past, several recent blogs will first introduce some of the maven-ssm-web not in the new content (because more familiar!) ); Maven-ssm-web more recently, if a friend still needs, will continue to update; the Spring Boot Integration project is:spring-boot-integrate, the series works are: spring-boot-2.0.3.
This series of projects are based on spring-boot-2.0.3; This is the first article, first of all, to talk about the internationalization of spring boot, Project address:spring-boot-i18n
Basic version
Pom.xml:
<?xml version= "1.0" encoding= "UTF-8"? ><project xmlns= "http://maven.apache.org/POM/4.0.0"Xmlns:xsi= "Http://www.w3.org/2001/XMLSchema-instance"xsi:schemalocation= "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" > <modelversion>4.0.0 </modelVersion> <groupid>com .lee</groupid> <artifactid>spring-boot-i18n</artifactid > <version>1.0-SNAPSHOT</version> <properties> <java.version>1.8</java.version& Gt </properties> <parent> <groupId>org.springframework.boot</groupId> <artifactid >spring-boot-starter-parent</artifactId> <version>2.0.3.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactid>spring-boot-starter-thymeleaf </artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactid>spring-boot-maven-plugin</arti factid> </plugin> </plugins> </build></project>
Application.yml
Server: 8880Spring: #国际化配置 messages: encoding:utf-8 basename:i18n/Messages # Thymeleaf configuration thymeleaf: false
I18nconfig.java
PackageCom.lee.i18n.config;ImportOrg.springframework.context.annotation.Bean;Importorg.springframework.context.annotation.Configuration;ImportOrg.springframework.web.servlet.LocaleResolver;ImportOrg.springframework.web.servlet.config.annotation.InterceptorRegistry;ImportOrg.springframework.web.servlet.config.annotation.WebMvcConfigurer;ImportOrg.springframework.web.servlet.i18n.CookieLocaleResolver;Importorg.springframework.web.servlet.i18n.LocaleChangeInterceptor; @Configuration Public classI18nconfig {//Configuring the cookie Language parser@Bean Publiclocaleresolver Localeresolver () {cookielocaleresolver resolver=NewCookielocaleresolver (); Resolver.setcookiemaxage (3600);//cookie effective duration, in secondsResolver.setcookiename ("Language");//set the stored cookie name to language returnResolver; } //Configure an interceptor to intercept changes in internationalized languages@Bean Publicwebmvcconfigurer Webmvcconfigurer () {return NewWebmvcconfigurer () {//Interception Device@Override Public voidaddinterceptors (Interceptorregistry registry) {Registry.addinterceptor (NewLocalechangeinterceptor ()). Addpathpatterns ("/**"); } }; }}
View Code
Logincontroller.java
PackageCom.lee.i18n.controller;ImportOrg.springframework.stereotype.Controller;Importorg.springframework.web.bind.annotation.RequestMapping; @Controller Public classLogincontroller {@RequestMapping ("/login") PublicString Login () {return"Login"; } @RequestMapping ("/index") PublicString Index () {return"Index"; }}
View Code
Messages.properties
Index.welcome= Welcome Login.username= Login name Login.password= password Login.login= login
Messages_en_us.properties
Index.welcome=welcomelogin.username=Usernamelogin.password=Passwordlogin.login= Login
Messages_zh_cn.properties
Index.welcome= Welcome Login.username= Login name Login.password= password Login.login= login
When the file is configured well (other can go to spring-boot-i18n pull ), are configured well, the project ran up, we come to see the results, whether to achieve the internationalization effect? The answer is YES!
Premium Edition
The basic version has a drawback, is that the international resources are written in a file: Messages*.properties, the content is written in a file has a fatal disadvantage: the larger the file, the more difficult to maintain;
So where's the premium version? You are right, is the resource in a certain nature or function into a resource folder, and then in the Resource folder to decentralize specific resource files, such as
The contents of the changes have been marked, the content of the specific changes can go to spring-boot-i18n pull; Engineering run, let's see the results.
SOURCE Inquiry
From the initialization of the two containers to see the whole process, which is the two containers, one is the spring root container, one is the Spring MVC container, the spring root container is the root context: webapplicationcontext,spring The MVC container is: dispatcherservlet;
Spring Root Container initialization
Let's start with the main function, such as
Initmessagesource (): Initializes an internationalized resource, finishbeanfactoryinitialization (beanfactory) instantiates non-deferred initialization of the Bean;spring container initialization content is still very much, Interested friends can follow the breakpoint debugging detailed look at the initialization of the session process; All the beans are defined in the Defaultlistablebeanfactory beandefinitionmap, Subsequent instances of the bean definition are obtained from BEANDEFINITIONMAP.
Spring MVC container Initialization
We all know that the core class of spring MVC is dispatcherservlet, and we'll start with him, like:
From the Dispatcherservlet inheritance relationship, Httpservletbean inherits the HttpServlet, so the Init method is called when the Web container starts. We can use this as a portal to track the initialization of Dispatcherservlet, and the Initstrategies method in Dispatcherservlet is important, and initlocaleresolver (context) and inithandlermappings (context) and the internationalization of this article is directly related, initlocaleresolver (context) Binds our own defined localeresolver to the Dispatcherservlet attribute Localeresolver; inithandlermappings (context) Add our own new interceptor Localechangeinterceptor to the Dispatcherservlet handlermappings;
Is it a wonderful feeling that some of our custom beans are associated with dispatcherservlet, and our request URL must go through Dispatcherservlet, is that a coincidence? It's obviously not! If you're still confused, I'm sorry! We went on to look down ...
Request process
From Dispatcherservlet's inheritance, the request passes through the Dispatcherservlet Doservice method, Doservice binds the Localeresolver in Dispatcherservlet (that is, the Cookielocaleresolver object we define) to the current request object. Then call Dodispatch to forward the request;
Class inheritance diagram for Localechangeinterceptor
It is known that it inherits the Handlerinterceptor, and rewrite the Prehandle, we start from the Localechangeinterceptor Prehandle method (the request will certainly go through this method) read the source code, interrupt point tracking, as follows
Since the locale parameter can be aware of language changes, it is also possible to load the corresponding resources according to the language, so as to achieve internationalization (how to load the need for everyone to read the source code!) )
Source reading this end, is not particularly fine, but provides a main process; We strongly recommend that you read the source code when the breakpoint debugging tracking, not easy to lose!
Reference
Do your own spring-boot to strengthen the internationalization function
Chapter Three Dispatcherservlet--the study of SPRINGMVC with Tao