本文的迁移背景是: 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.xmlspring-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 filterRegistrationBean() {
    FilterRegistrationBean bean = new FilterRegistrationBean(new MyFilter());
    // Mapping filter to a Servlet
    bean.addServletRegistrationBeans(new ServletRegistrationBean[] {
          servletRegistrationBean() 
       });
    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);
    }
}