本文的迁移背景是: JDK7 + SpringMVC + 传统的 web.xml + 外部Tomcat 迁移到 JDK8 + SpringBoot2 + 嵌入式的Tomcat

pom 注意事项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<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.xmlspring-servlet.xml

1
2
3
@Configuration
public class WebConfig implements WebMvcConfigurer, WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
}

添加 interceptor

1
2
3
4
@Override
public void addInterceptors(final InterceptorRegistry registry) {
registry.addInterceptor(adminHandlerInterceptor).addPathPatterns("/admin/**");
}

注册 servlet

1
2
3
4
5
@Bean
public ServletRegistrationBean servletRegistrationBean() {
ServletRegistrationBean bean = new ServletRegistrationBean(new MyServlet(), "/myServlet");
return bean;
}

注册 filter

1
2
3
4
5
6
@Bean
public FilterRegistrationBean<YourFilter> filterFilterRegistrationBean() {
final FilterRegistrationBean<StubLoggingFilter> bean = new FilterRegistrationBean<>(new YourFilter());
bean.addUrlPatterns("/*");
return bean;
}

注册 ServletContextListener

1
2
3
4
5
6
7
8
@Bean
public ServletListenerRegistrationBean<ServletContextListener> listenerRegistrationBean() {
ServletListenerRegistrationBean<ServletContextListener> bean =
new ServletListenerRegistrationBean<>();
bean.setListener(new MyServletContextListener());
return bean;
}

修改tomcat默认端口

1
2
3
4
5
@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 等同理

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
/**
* @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

1
2
3
4
5
6
7
8
9
10
@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 文件

1
@PropertySource({"classpath:rabbit.queue.properties", "classpath:weibo4j.properties"})

添加 main 方法

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
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);
}
}