Spring MVC Java Config (конфигурация с аннотациями) для mvc-config.xml
Пример преобразования mvc-config.xml в конфигурацию Spring MVC Java Config (конфигурация с аннотациями).
Обзор приложения Spring MVC + AngularJS + Bootstrap + HTML5
Используемые технологии и библиотеки
- Spring MVC 4.2.4.Release
1. Описание задачи
Преобразовать mvc-config.xml в аналогичный по функционалу Java класс с использованием аннотаций.
2. Структура проекта
Это продолжение первой статьи по преобразованию xml конфигурации приложения на Java конфигурацию.
3. mvc-config.xml
mvc-config.xml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:security="http://www.springframework.org/schema/security" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd"> <!--Spring security enabled annotations--> <security:global-method-security pre-post-annotations="enabled" secured-annotations="enabled" jsr250-annotations="enabled"/> <!-- context:component-scan This tag will scan @Component, @Repository, @Service, @Controller and also resolves @Autowired and @Qualifier --> <context:component-scan base-package="ru.javastudy.mvcHtml5Angular.mvc" /> <!-- mvc:annotation-driven configures Spring MVC annotations Support for validating @Controller inputs with @Valid, if a JSR-303 Provider is present on the classpath. HttpMessageConverter support for @RequestBody method parameters and @ResponseBody method return values from @RequestMapping or @ExceptionHandler methods. --> <mvc:annotation-driven> <!--use int RestController to produce pretty json response--> <mvc:message-converters> <bean id="jacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="prettyPrint" value="true" /> </bean> </mvc:message-converters> </mvc:annotation-driven> <!-- activate @Transactional JPA annotation --> <tx:annotation-driven/> <!-- ViewResolver bean config for mapping strings to jsp views --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- Example: a logical view name of 'showMessage' is mapped to '/WEB-INF/jsp/showMessage.jsp' --> <property name="order" value="1" /> <property name="prefix" value="/WEB-INF/view/" /> <property name="suffix" value=".jsp" /> </bean> <!-- File Upload bean config--> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- set the maximum file size in bytes --> <property name="maxUploadSize" value="1000000"/> </bean> <!--Excel and PDF xml view configuration --> <!--disabling for jUnit test. --> <bean class="org.springframework.web.servlet.view.XmlViewResolver"> <property name="order" value="0" /> <property name="location" value="/excel-pdf-config.xml"/> </bean> <mvc:view-controller path="/" view-name="/index"/> <mvc:view-controller path="/index.html" view-name="/index"/> <mvc:view-controller path="/login.html" view-name="/form/login"/> <mvc:view-controller path="/about.html" view-name="/about/about"/> <mvc:view-controller path="/file.html" view-name="/file/file"/> <mvc:view-controller path="/jdbc.html" view-name="/jdbc/jdbc"/> <mvc:view-controller path="/email.html" view-name="/email/email"/> <mvc:view-controller path="/rest.html" view-name="/rest/rest"/> <mvc:view-controller path="/orm.html" view-name="/orm/orm"/> <mvc:view-controller path="/jstl.html" view-name="/jstl/jstl"/> <mvc:view-controller path="/scope.html" view-name="/scope/scope"/> <mvc:view-controller path="/cookie.html" view-name="/cookie/cookieView"/> <mvc:view-controller path="/security.html" view-name="/security/security"/> <mvc:view-controller path="/security/admin.html" view-name="/security/admin"/> <mvc:view-controller path="/angularIndex.html" view-name="/angularjs/angularindex"/> <mvc:view-controller path="/angularjson.html" view-name="/angularjs/angularjson"/> <mvc:view-controller path="/expressions.html" view-name="/angularjs/expressions"/> <mvc:view-controller path="/ng-bind-model.html" view-name="/angularjs/ng-bind-model"/> <mvc:view-controller path="/ng-class.html" view-name="/angularjs/ng-class"/> <mvc:view-controller path="/ng-click-show.html" view-name="/angularjs/ng-click-show"/> <mvc:view-controller path="/ng-if-switch.html" view-name="/angularjs/ng-if-switch"/> <mvc:view-controller path="/ng-init.html" view-name="/angularjs/ng-init"/> <mvc:view-controller path="/ng-repeat.html" view-name="/angularjs/ng-repeat"/> <mvc:view-controller path="/two-way-binding.html" view-name="/angularjs/two-way-binding"/> <mvc:view-controller path="/angularDI.html" view-name="/angularjs/angularDI"/> <mvc:view-controller path="/ng-controller.html" view-name="/angularjs/ng-controller"/> <mvc:view-controller path="/angularfilters.html" view-name="/angularjs/filters"/> <mvc:view-controller path="/angularvalidation.html" view-name="/angularjs/validation"/> <mvc:view-controller path="/angularrouting.html" view-name="/angularjs/routing"/> <mvc:view-controller path="/angularhttpresource.html" view-name="/angularjs/httpresource"/> <mvc:view-controller path="/customdirective.html" view-name="/angularjs/customdirective"/> <mvc:view-controller path="/html5.html" view-name="/html5/html5"/> <!-- Static Resources Configuration (get access to static sources such as CSS and JavaScript files) --> <mvc:resources mapping="/resources/**" location="/resources/" /> <!-- themes can be put in different folder such as <mvc:resources mapping="/resources/**" location="/resources/themeBlue" /> <mvc:resources mapping="/resources/**" location="/resources/themeGreen" /> --> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/interceptorCall/*"/> <!--need to use ' /** ' not ' /* ' if you want to intercept all requests.--> <!--<mvc:mapping path="/**"/>--> <bean class="ru.javastudy.mvcHtml5Angular.mvc.interceptors.SiteInterceptor"/> </mvc:interceptor> <mvc:interceptor> <mvc:mapping path="/*" /> <bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"> <property name="paramName" value="languageVar" /> </bean> </mvc:interceptor> </mvc:interceptors> <bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver"> <property name="defaultLocale" value="ru" /> <!-- cookieMaxAge in seconds. if you set it to -1, the cookie will be deleted when browser is closed) --> <property name="cookieMaxAge" value="100000"/> </bean> <!-- MessageSource ReloadableResourceBundleMessageSource configuration --> <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <property name="basenames" value="classpath:/locales/messages"/> <property name="cacheSeconds" value="1"/> <property name="defaultEncoding" value="UTF-8" /> </bean> </beans> |
Вот эту конфигурацию мы будем преобразовывать в Java класс с использованием аннотаций.
4. MVCConfig
Для начала приведу полный файл MVCConfig.java, который соответствует mvc-config.xml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
package ru.javastudy.mvcHtml5Angular.javaconfig; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.support.ReloadableResourceBundleMessageSource; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.web.multipart.commons.CommonsMultipartResolver; import org.springframework.web.servlet.config.annotation.*; import org.springframework.web.servlet.i18n.CookieLocaleResolver; import org.springframework.web.servlet.i18n.LocaleChangeInterceptor; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.XmlViewResolver; import ru.javastudy.mvcHtml5Angular.mvc.interceptors.SiteInterceptor; import java.util.List; import java.util.Locale; /** * Created for JavaStudy.ru on 28.05.2016. * mvc-config.xml analogue */ @EnableWebMvc //<mvc:annotation-driven> @Configuration @ComponentScan(basePackages = {"ru.javastudy.mvcHtml5Angular.mvc"}) //<context:component-scan base-package=''> public class MVCConfig extends WebMvcConfigurerAdapter { /** * <mvc:resources mapping="/resources/**" location="/resources/" /> */ @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/resources/**").addResourceLocations("/resources/"); } /** * bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> */ @Bean public InternalResourceViewResolver jspViewResolver() { InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); viewResolver.setOrder(1); viewResolver.setPrefix("/WEB-INF/view/"); viewResolver.setSuffix(".jsp"); return viewResolver; } /** * <mvc:view-controller path="/about.html" view-name="/about/about"/> */ @Override public void addViewControllers(ViewControllerRegistry registry) { super.addViewControllers(registry); registry.addViewController("/").setViewName("forward:/index.html"); registry.addViewController("/about.html").setViewName("/about/about"); registry.addViewController("/index.html").setViewName("/index"); registry.addViewController("/").setViewName("/index"); registry.addViewController("/index.html").setViewName("/index"); registry.addViewController("/login.html").setViewName("/form/login"); registry.addViewController("/about.html").setViewName("/about/about"); registry.addViewController("/file.html").setViewName("/file/file"); registry.addViewController("/jdbc.html").setViewName("/jdbc/jdbc"); registry.addViewController("/email.html").setViewName("/email/email"); registry.addViewController("/rest.html").setViewName("/rest/rest"); registry.addViewController("/orm.html").setViewName("/orm/orm"); registry.addViewController("/jstl.html").setViewName("/jstl/jstl"); registry.addViewController("/scope.html").setViewName("/scope/scope"); registry.addViewController("/cookie.html").setViewName("/cookie/cookieView"); registry.addViewController("/security.html").setViewName("/security/security"); registry.addViewController("/security/admin.html").setViewName("/security/admin"); registry.addViewController("/angularIndex.html").setViewName("/angularjs/angularindex"); registry.addViewController("/angularjson.html").setViewName("/angularjs/angularjson"); registry.addViewController("/expressions.html").setViewName("/angularjs/expressions"); registry.addViewController("/ng-bind-model.html").setViewName("/angularjs/ng-bind-model"); registry.addViewController("/ng-class.html").setViewName("/angularjs/ng-class"); registry.addViewController("/ng-click-show.html").setViewName("/angularjs/ng-click-show"); registry.addViewController("/ng-if-switch.html").setViewName("/angularjs/ng-if-switch"); registry.addViewController("/ng-init.html").setViewName("/angularjs/ng-init"); registry.addViewController("/ng-repeat.html").setViewName("/angularjs/ng-repeat"); registry.addViewController("/two-way-binding.html").setViewName("/angularjs/two-way-binding"); registry.addViewController("/angularDI.html").setViewName("/angularjs/angularDI"); registry.addViewController("/ng-controller.html").setViewName("/angularjs/ng-controller"); registry.addViewController("/angularfilters.html").setViewName("/angularjs/filters"); registry.addViewController("/angularvalidation.html").setViewName("/angularjs/validation"); registry.addViewController("/angularrouting.html").setViewName("/angularjs/routing"); registry.addViewController("/angularhttpresource.html").setViewName("/angularjs/httpresource"); registry.addViewController("/customdirective.html").setViewName("/angularjs/customdirective"); registry.addViewController("/html5.html").setViewName("/html5/html5"); } @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { converters.add(getJacksonHttpMessageConverter()); } @Bean(name = "jacksonHttpMessageConverter") public MappingJackson2HttpMessageConverter getJacksonHttpMessageConverter() { MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); converter.setPrettyPrint(true); return converter; } /** * <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> */ @Bean(name = "multipartResolver") public CommonsMultipartResolver getMultipartResolver() { CommonsMultipartResolver cmr = new CommonsMultipartResolver(); cmr.setMaxUploadSize(1000000); return cmr; } /** * <bean class="org.springframework.web.servlet.view.XmlViewResolver"> */ @Bean(name = "xmlViewResolver") public XmlViewResolver getXmlViewResolver() { XmlViewResolver xmlViewResolver = new XmlViewResolver(); Resource resource = new ClassPathResource("excel-pdf-config.xml");//note it in java resources, not webapp xmlViewResolver.setOrder(0); xmlViewResolver.setLocation(resource); return xmlViewResolver; } /** * <mvc:interceptors> */ @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(siteInterceptor).addPathPatterns("/interceptorCall/*"); registry.addInterceptor(getLocaleChangeInterceptor()).addPathPatterns("/*"); } @Bean(name = "localeChangeInterceptor") public LocaleChangeInterceptor getLocaleChangeInterceptor() { LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor(); localeChangeInterceptor.setParamName("languageVar"); return localeChangeInterceptor; } @Autowired private SiteInterceptor siteInterceptor; /** * <bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver"> */ @Bean(name = "localeResolver") public CookieLocaleResolver getLocaleResolver() { CookieLocaleResolver cookieLocaleResolver = new CookieLocaleResolver(); cookieLocaleResolver.setDefaultLocale(new Locale("ru")); cookieLocaleResolver.setCookieMaxAge(100000); return cookieLocaleResolver; } /** * <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> */ @Bean(name = "messageSource") public ReloadableResourceBundleMessageSource getMessageSource() { ReloadableResourceBundleMessageSource resource = new ReloadableResourceBundleMessageSource(); resource.setBasename("classpath:/locales/messages"); resource.setCacheSeconds(1); resource.setDefaultEncoding("UTF-8"); return resource; } } |
Теперь разобьем их по частям.
4.1. context:component-scan
1 |
<context:component-scan base-package="ru.javastudy.mvcHtml5Angular.mvc" /> |
и
1 |
@ComponentScan(basePackages = {"ru.javastudy.mvcHtml5Angular.mvc"}) |
4.2. mvc:annotation-driven и mvc:message-converters
1 2 3 4 5 6 7 8 |
<mvc:annotation-driven> <!--use int RestController to produce pretty json response--> <mvc:message-converters> <bean id="jacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="prettyPrint" value="true" /> </bean> </mvc:message-converters> </mvc:annotation-driven> |
и
1 2 3 4 5 6 7 8 |
@EnableWebMvc //<mvc:annotation-driven> public class MVCConfig extends WebMvcConfigurerAdapter { ... @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { converters.add(getJacksonHttpMessageConverter()); } |
4.3. tx:annotation-driven
1 2 |
<!-- activate @Transactional JPA annotation --> <tx:annotation-driven/> |
и
1 2 |
@EnableTransactionManagement public class MVCConfig extends WebMvcConfigurerAdapter { |
4.4. bean class = «org.springframework.web.servlet.view.InternalResourceViewResolver»
1 2 3 4 5 6 7 |
<!-- ViewResolver bean config for mapping strings to jsp views --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- Example: a logical view name of 'showMessage' is mapped to '/WEB-INF/jsp/showMessage.jsp' --> <property name="order" value="1" /> <property name="prefix" value="/WEB-INF/view/" /> <property name="suffix" value=".jsp" /> </bean> |
Этот же бин в java config:
1 2 3 4 5 6 7 8 |
@Bean public InternalResourceViewResolver jspViewResolver() { InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); viewResolver.setOrder(1); viewResolver.setPrefix("/WEB-INF/view/"); viewResolver.setSuffix(".jsp"); return viewResolver; } |
4.5. bean id = «multipartResolver» class=»org.springframework.web.multipart.commons.CommonsMultipartResolver»
1 2 3 4 5 |
<!-- File Upload bean config--> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- set the maximum file size in bytes --> <property name="maxUploadSize" value="1000000"/> </bean> |
аналог
1 2 3 4 5 6 |
@Bean(name = "multipartResolver") public CommonsMultipartResolver getMultipartResolver() { CommonsMultipartResolver cmr = new CommonsMultipartResolver(); cmr.setMaxUploadSize(1000000); return cmr; } |
4.6. bean class = «org.springframework.web.servlet.view.XmlViewResolver»
1 2 3 4 |
<bean class="org.springframework.web.servlet.view.XmlViewResolver"> <property name="order" value="0" /> <property name="location" value="/excel-pdf-config.xml"/> </bean> |
Здесь стоит обратить внимание, что excel-pdf-config.xml не переписывался, а был перенесен в src/resources. Он выглядит так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- When a controller returns excelDocument render the model with the spring.mvc.excelpdf.ExcelDocument class --> <bean id="excelDocument" class="ru.javastudy.mvcHtml5Angular.mvc.excelpdf.ExcelDocument" /> <!-- When a controller returns pdfDocument render the model with the spring.mvc.excelpdf.PDFDocument class --> <bean id="pdfDocument" class="ru.javastudy.mvcHtml5Angular.mvc.excelpdf.PDFDocument"/> </beans> |
Аналог в Java конфигурации следующий:
1 2 3 4 5 6 7 8 |
@Bean(name = "xmlViewResolver") public XmlViewResolver getXmlViewResolver() { XmlViewResolver xmlViewResolver = new XmlViewResolver(); Resource resource = new ClassPathResource("excel-pdf-config.xml");//note it in java resources, not webapp xmlViewResolver.setOrder(0); xmlViewResolver.setLocation(resource); return xmlViewResolver; } |
4.7. mvc:view-controller path = «/» view-name = «/index»
1 2 3 4 5 6 7 |
<mvc:view-controller path="/" view-name="/index"/> <mvc:view-controller path="/index.html" view-name="/index"/> <mvc:view-controller path="/login.html" view-name="/form/login"/> <mvc:view-controller path="/about.html" view-name="/about/about"/> <mvc:view-controller path="/file.html" view-name="/file/file"/> //и т.д. |
в классе:
1 2 3 4 5 6 7 8 |
@Override public void addViewControllers(ViewControllerRegistry registry) { super.addViewControllers(registry); registry.addViewController("/").setViewName("forward:/index.html"); registry.addViewController("/about.html").setViewName("/about/about"); registry.addViewController("/index.html").setViewName("/index"); //и т.д. |
4.8. mvc:resources mapping = «/resources/**» location = «/resources/»
1 |
<mvc:resources mapping="/resources/**" location="/resources/" /> |
эта же настройка в программной конфигурации:
1 2 3 4 |
@Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/resources/**").addResourceLocations("/resources/"); } |
4.9. mvc:interceptors
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/interceptorCall/*"/> <!--need to use ' /** ' not ' /* ' if you want to intercept all requests.--> <!--<mvc:mapping path="/**"/>--> <bean class="ru.javastudy.mvcHtml5Angular.mvc.interceptors.SiteInterceptor"/> </mvc:interceptor> <mvc:interceptor> <mvc:mapping path="/*" /> <bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"> <property name="paramName" value="languageVar" /> </bean> </mvc:interceptor> </mvc:interceptors> |
Перехватчики с помощью Java кода:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
@Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(siteInterceptor).addPathPatterns("/interceptorCall/*"); registry.addInterceptor(getLocaleChangeInterceptor()).addPathPatterns("/*"); } @Bean(name = "localeChangeInterceptor") public LocaleChangeInterceptor getLocaleChangeInterceptor() { LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor(); localeChangeInterceptor.setParamName("languageVar"); return localeChangeInterceptor; } @Autowired private SiteInterceptor siteInterceptor; |
где SiteInterceptor — компонент (бин) из пакета interceptors. Описан в теме о перехватчиках (см. содержание).
4.10. bean id = «localeResolver» class = «org.springframework.web.servlet.i18n.CookieLocaleResolver»
Переключение локали
1 2 3 4 5 |
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver"> <property name="defaultLocale" value="ru" /> <!-- cookieMaxAge in seconds. if you set it to -1, the cookie will be deleted when browser is closed) --> <property name="cookieMaxAge" value="100000"/> </bean> |
или
1 2 3 4 5 6 7 |
@Bean(name = "localeResolver") public CookieLocaleResolver getLocaleResolver() { CookieLocaleResolver cookieLocaleResolver = new CookieLocaleResolver(); cookieLocaleResolver.setDefaultLocale(new Locale("ru")); cookieLocaleResolver.setCookieMaxAge(100000); return cookieLocaleResolver; } |
4.11. bean id = «messageSource» class = «org.springframework.context.support.ReloadableResourceBundleMessageSource»
1 2 3 4 5 6 |
<!-- MessageSource ReloadableResourceBundleMessageSource configuration --> <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <property name="basenames" value="classpath:/locales/messages"/> <property name="cacheSeconds" value="1"/> <property name="defaultEncoding" value="UTF-8" /> </bean> |
MessageSource в java классе выглядит так:
1 2 3 4 5 6 7 8 |
@Bean(name = "messageSource") public ReloadableResourceBundleMessageSource getMessageSource() { ReloadableResourceBundleMessageSource resource = new ReloadableResourceBundleMessageSource(); resource.setBasename("classpath:/locales/messages"); resource.setCacheSeconds(1); resource.setDefaultEncoding("UTF-8"); return resource; } |
Другие части перехода с xml на Java конфигурацию
Spring MVC Java Config (конфигурация с аннотациями) для web.xml
Spring MVC Java Config (конфигурация с аннотациями) для Spring Security (security-config.xml)
Spring MVC Java Config (конфигурация с аннотациями) для application-context.xml
Исходный код
23. Annotations config — проект в IDEA
8