spring项目升级springboot

插件准备: maven helper 解决包冲突必备神器。
目标:将原始项目的spring 版本4.3.22.RELEASE,升级为springboot 的2.3.5.RELEASE版本,步骤如下:

加入springboot包,并且改war包为jar包

    <packaging>jar</packaging>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <!-- Import dependency management from Spring Boot -->
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${version.springboot}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
   <!--spring boot-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
  • 同步springframework版本号,也就是移除掉springframework系列包中指定的version,spring的版本会自动和dependencyManagement的spring版本一致

  • 创建启动类,把原来的xml的配置文件包含进去

    @SpringBootApplication(exclude = {RedisRepositoriesAutoConfiguration.class, DataSourceAutoConfiguration.class, RedisAutoConfiguration.class, KafkaAutoConfiguration.class, MongoDataAutoConfiguration.class, MongoRepositoriesAutoConfiguration.class})
    @ImportResource(locations = {"/spring/applicationContext.xml"})
    public class Application {
        public static void main(String[] args) {
            SpringApplication.run(CustNotifyApplication .class, args);
    

    增加springboot打包插件

                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <configuration>
                        <mainClass>com.demo.manage.Application</mainClass>
                    </configuration>
                    <executions>
                        <execution>
                            <goals>
                                <goal>repackage</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
    

    原先的disconf是xml方式配置的,看得不舒服,索性干掉了下面的xml配置:

    <?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:aop="http://www.springframework.org/schema/aop"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans.xsd
                            http://www.springframework.org/schema/aop
                            http://www.springframework.org/schema/aop/spring-aop.xsd">
     <aop:aspectj-autoproxy proxy-target-class="true" />
     <!-- disconf配置 -->
     <bean id="disconfMgrBean" class="com.baidu.disconf.client.DisconfMgrBean"
         destroy-method="destroy">
         <property name="scanPackage" value="com.demo.manage" />
     </bean>
     <bean id="disconfMgrBean2" class="com.baidu.disconf.client.DisconfMgrBeanSecond"
         init-method="init" destroy-method="destroy">
     </bean>
     <bean id="configproperties_no_reloadable_disconf"
         class="com.baidu.disconf.client.addons.properties.ReloadablePropertiesFactoryBean">
         <property name="locations">
                 <value>redis.properties</value>
                 <value>dubbo.properties</value>
                 <value>kafka.properties</value>
                 <value>kafka.consumer.config.properties</value>
                 <value>db.properties</value>
             </list>
         </property>
     </bean>
     <bean id="hostBindProperties" class="com.demo.common.util.PropertiesFactoryBean">
         <property name="fileLists">
                 <value>config/host-bind.properties</value>
             </list>
         </property>
     </bean>
     <!-- 使用托管方式的disconf配置(无代码侵入, 配置更改不会自动reload) -->
     <bean id="propertyConfigurerForNoReload"
         class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
         <property name="ignoreResourceNotFound" value="false" />
         <property name="ignoreUnresolvablePlaceholders" value="false" />
         <property name="propertiesArray">
                 <ref bean="configproperties_no_reloadable_disconf" />
                 <ref bean="hostBindProperties" />
             </list>
         </property>
     </bean>
    </beans>
    

    application.yaml中加入disconf配置:

    server:
      port: 8080
      shutdown: graceful
    spring:
      application:
        name: demo-server
      profiles:
        active: ${profile.active}
      main:
        allow-bean-definition-overriding: true
      jackson:
        time-zone: GMT+8
    dubbo:
      protocol:
        host: 127.0.0.1
    # disconf config
    disconf:
      scanPackage: com.demo.manage
      version: ${disconf.version}
      env: ${disconf.env}
      conf_server_host: ${disconf.server.host}
      files: redis.properties,dubbo.properties,kafka.properties,kafka.consumer.config.properties,db.properties
      app: demo-server
      debug: false
      enable:
        remote:
          conf: true
      conf_server_url_retry_times: 3
      conf_server_url_retry_sleep_seconds: 5
      user_define_download_dir: /app/spring-boot/demo-server/disconf
      enable_local_download_dir_in_class_path: false
    

    在pom中加入了springboot的disconf启动包

            <dependency>
                <groupId>com.fcbox</groupId>
                <artifactId>spring-boot-starter-disconf</artifactId>
                <version>2.0.0</version>
            </dependency>
    

    修改环境变量配置命名规范。

  • 将pom中的profiles.activation修改为profile.active

  • logback文件按照配置环境区分配置:

        <springProfile name="dev,local,per,pet,uat,uat1,uat2,uat3,uat4,uat5,uat6,uat7">
            <root level="INFO">
                <appender-ref ref="CONSOLE"/>
                <appender-ref ref="notify_log"/>
                <appender-ref ref="error_log"/>
            </root>
        </springProfile>
        <springProfile name="prd,stg">
            <root level="INFO">
                <appender-ref ref="notify_log"/>
                <appender-ref ref="error_log"/>
            </root>
        </springProfile>
    

    第三方sdk包中使用classpath读取不到配置文件,可以使用绝对路径加载,如:

     <bean id="personalPaymentService" class="com.demo.payment.client.impl.PersonalPaymentServiceImpl" >
         <property name="configPath" value="file:/app/spring-boot/demo-server/disconf/payment_common.properties" />
     </bean>
    

    包冲突问题

    jackson版本冲突,报错信息:Caused by: java.lang.NoClassDefFoundError: com/fasterxml/jackson/datatype/jsr310/ser/ZoneIdSerializer。直接升级到最高版本2.12.0,然后干掉版本不一致的jackson包,涉及的jackson包为:

            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-core</artifactId>
                <version>2.12.0</version>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
                <version>2.12.0</version>
                <exclusions>
                    <exclusion>
                        <artifactId>jackson-core</artifactId>
                        <groupId>com.fasterxml.jackson.core</groupId>
                    </exclusion>
                    <exclusion>
                        <artifactId>jackson-annotations</artifactId>
                        <groupId>com.fasterxml.jackson.core</groupId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-annotations</artifactId>
                <version>2.12.0</version>
            </dependency>
    

    log4j包缺失报错 java.lang.ClassNotFoundException: org.apache.log4j.Logger。dubbo使用了 log4j所以需要引入log4j包:

            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>log4j-over-slf4j</artifactId>
                <version>1.7.30</version>
            </dependency>
    
  • jedis包冲突 java.lang.ClassNotFoundException: redis.clients.jedis.util.Pool 排除掉jedis低版本包

  • Redis配置读取本地文件,需要改为Spring-map加载

    <bean id="mallResourcePropertySource"
         class="org.springframework.core.io.support.ResourcePropertySource">
       <constructor-arg name="name" value="mall-redis-conf.properties"/>
       <constructor-arg name="resource"
                    value="classpath:mall-redis-conf.properties"/>
    </bean>
    上面代码改为
    <bean id="resourcePropertySource"
         class="org.springframework.core.env.PropertiesPropertySource">
       <constructor-arg name="name" value="mall-redis-conf.properties"/>
       <constructor-arg name="source">
             <entry key="spring.redis.cluster.max-redirects" value="${spring.redis.cluster.max-redirects}" />
             <entry key="spring.redis.cluster.nodes" value="${spring.redis.cluster.nodes}"/>
       </constructor-arg>
    </bean>