从传统SpringMVC迁移到SpringBoot
Contents
本文的迁移背景是: JDK7 + SpringMVC + 传统的 web.xml + 外部Tomcat 迁移到 JDK8 + SpringBoot2 + 嵌入式的Tomcat
pom 注意事项
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
<!--<include>**/*.json</include>-->
<!--<include>**/*.properties</include>-->
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
</build>
改造 web.xml
或 spring-servlet.xml
@Configuration
public class WebConfig implements WebMvcConfigurer, WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
}
添加 interceptor
@Override
public void addInterceptors(final InterceptorRegistry registry) {
registry.addInterceptor(adminHandlerInterceptor).addPathPatterns("/admin/**");
}
注册 servlet
@Bean
public ServletRegistrationBean servletRegistrationBean() {
ServletRegistrationBean bean = new ServletRegistrationBean(new MyServlet(), "/myServlet");
return bean;
}
注册 filter
@Bean
public FilterRegistrationBean<YourFilter> filterFilterRegistrationBean() {
final FilterRegistrationBean<StubLoggingFilter> bean = new FilterRegistrationBean<>(new YourFilter());
bean.addUrlPatterns("/*");
return bean;
}
注册 ServletContextListener
@Bean
public ServletListenerRegistrationBean<ServletContextListener> listenerRegistrationBean() {
ServletListenerRegistrationBean<ServletContextListener> bean =
new ServletListenerRegistrationBean<>();
bean.setListener(new MyServletContextListener());
return bean;
}
修改tomcat默认端口
@Override
public void customize(final ConfigurableServletWebServerFactory factory) {
factory.setPort(serverPort);
Loggers.RUNNING_LOG.info("init web server with port: {}", serverPort);
}
配置多个 Redis 或 RabbitMQ
主要是要为多个@Bean之一, 添加一个 @Primary 注解, 以免 Spring 会报冲突问题
多个 RabbitMQ 等同理
/**
* @author emacsist
*/
@Configuration
public class RedisConfig {
@Bean
@Primary
public LettuceConnectionFactory jedisConnectionFactory() {
return new LettuceConnectionFactory(getRedisStandaloneConfiguration(webHost, webPort, webPwd, webDB));
}
@Bean
@Primary
public RedisTemplate<String, String> redisTemplate(@Autowired @Qualifier("jedisConnectionFactory") LettuceConnectionFactory jedisConnectionFactory, @Autowired StringRedisSerializer stringRedisSerializer) {
return getRedisTemplate(jedisConnectionFactory, stringRedisSerializer);
}
public static RedisStandaloneConfiguration getRedisStandaloneConfiguration(final String host, final int port, final String pwd, final int db) {
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(host, port);
redisStandaloneConfiguration.setPassword(RedisPassword.of(pwd));
redisStandaloneConfiguration.setDatabase(db);
Loggers.RUNNING_LOG.info("inited redis connection factory {}:{}", host, port);
return redisStandaloneConfiguration;
}
public static RedisTemplate<String, String> getRedisTemplate(final LettuceConnectionFactory redisConnectionFactory, final StringRedisSerializer stringRedisSerializer) {
RedisTemplate<String, String> redisTemplate = new RedisTemplate();
redisTemplate.setConnectionFactory(redisConnectionFactory);
redisTemplate.setKeySerializer(stringRedisSerializer);
redisTemplate.setValueSerializer(stringRedisSerializer);
redisTemplate.setHashKeySerializer(stringRedisSerializer);
redisTemplate.setHashValueSerializer(stringRedisSerializer);
Loggers.RUNNING_LOG.info("inited redis template {}:{}", redisConnectionFactory.getHostName(), redisConnectionFactory.getPort());
return redisTemplate;
}
}
配置 redis 的 pub/sub
@Bean(destroyMethod = "destroy")
public RedisMessageListenerContainer webRedisMessageListnerContainer() {
final RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer();
redisMessageListenerContainer.setConnectionFactory(redisConnectionFactory);
redisMessageListenerContainer.addMessageListener(redisMessageListener, new ChannelTopic(resetCacheTopic));
redisMessageListenerContainer.addMessageListener(redisPropertiesMessageListener, new ChannelTopic(propertyTopic));
Loggers.RUNNING_LOG.info("init redis message container ok...");
return redisMessageListenerContainer;
}
导入多个 properties
文件
@PropertySource({"classpath:rabbit.queue.properties", "classpath:weibo4j.properties"})
添加 main
方法
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.ImportResource;
import org.springframework.context.annotation.PropertySource;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
/**
* @author emacsist
*/
@SpringBootApplication(exclude = {RedisAutoConfiguration.class, RabbitAutoConfiguration.class})
@EnableWebMvc
@EnableAspectJAutoProxy
@EnableScheduling
@ImportResource(locations = {"classpath:spring.xml"})
@PropertySource({"classpath:rabbit.queue.properties", "classpath:weibo4j.properties"})
public class UnidspApplication {
public static void main(String[] args) {
SpringApplication.run(UnidspApplication.class, args);
}
}