SpringMVC e @Configuration:registrar ConversionService e HttpMessageConverter
-
22-12-2019 - |
Pergunta
Eu realmente gosto do spring e do estilo @Configuration para me livrar da configuração baseada em xml.Eu o uso com sucesso para a camada de serviço e repositório.O que também adoro é o recurso de injeção de dependência e os utilitários JDO/JPA/Jdbc!
O que eu realmente não entendo é como funciona o Spring WebMVC.Há muita magia incontrolável para mim.(e com @EnableAutoConfiguration há ainda mais mágica introduzida.Bom para prototipagem fácil, difícil de manter).
É assim que configuro meu webapp:
public class SpringWebBooter implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigApplicationContext rootContext = new AnnotationConfigApplicationContext();
rootContext.register(SpringConfiguration.class); //main configuration class for all beans
rootContext.refresh();
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.setParent(rootContext);
ctx.register(SpringWebConfiguration.class); //web context configuration class
ServletRegistration.Dynamic api = servletContext.addServlet("api", new DispatcherServlet(ctx));
api.setLoadOnStartup(1);
api.addMapping("/api/*");
}
}
Agora quero adicionar conversores de tipo e httpMessageConverters, então na classe SpringWebConfiguration tentei:
@EnableWebMvc
@Configuration
@ComponentScan
public class SpringWebConfiguration {
//works but feels very *magic*
@Autowired
public void configureConversionService(FormattingConversionService conversionService) {
conversionService.addConverter(new PointConverter(GEOMETRY_FACTORY));
conversionService.addConverterFactory(new StringToEnumConverterFactory());
}
//not working yet
@Bean
public MappingJackson2HttpMessageConverter createJsonMessageConverter() {
ObjectMapper o = new ObjectMapper();
o.enable(SerializationFeature.INDENT_OUTPUT);
MappingJackson2HttpMessageConverter c = new MappingJackson2HttpMessageConverter();
c.setObjectMapper(o);
return c;
}
}
O que prefiro achar intuitivo é adicionar conversores de tipo e mensagem ao construir o servlet do despachante.Isso seria muito mais claro do que alguma ligação automática duvidosa ou criação de bean.Eu sempre "espero" que o Dispatcher Servlet capte internamente meus beans, mas geralmente é apenas tentativa e erro. É possível configurar o Spring Mvc de forma direta?Com menos instanciações mágicas e mais concretas e chamadas #addHttpMessageConverter(...) por exemplo?
O mesmo basicamente para ExceptionResolvers, RequestHandler e RequestAdapter.
janeiro
Solução
A maneira mais direta seria estender WebMvcConfigurationSupport
.Você pode configurar quase tudo dessa forma, substituindo os métodos.
Mas esteja ciente de que é uma maneira muito direta de configurar as coisas.Dá a você muito mais controle do que você tem agora ou do que WebMvcConfigurerAdapter
daria a você.Dos documentos:
If the customization options of {@link WebMvcConfigurer} do not expose
something you need to configure, consider removing the {@code @EnableWebMvc}
annotation and extending directly from {@link WebMvcConfigurationSupport}
overriding selected {@code @Bean} methods
Conversores de mensagens personalizados (ou customizados) podem ser adicionados substituindo configureMessageConverters
.
Outras dicas
Se você estender o Adaptador WebMvcConfigurer para sua configuração web, deve parecer um pouco menos mágico e também fornecer o gancho para configurar seus conversores de mensagens, bem como vários outros componentes.
@Configuration
@ComponentScan
@EnableWebMvc
public class WebConfiguration extends WebMvcConfigurerAdapter
{
@Autowired
private CustomObjectMapper domainMapper;
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters)
{
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setObjectMapper(domainMapper);
converters.add(converter);
super.configureMessageConverters(converters);
}
}