Spring迁移为SpringBoot遇到的一些坑

由于公司需要,之前进行了Spring项目迁移为SpringBoot项目的工作。期间遇到了许多坑,一直没有解决,勉强采取其它方式绕过去了。在求助百度的过程中,发现了一句话:

Spring Boot的限制:

将现有或传统的Spring Framework项目转换为Spring Boot应用程序是一个非常困难和耗时的过程。它仅适用于全新Spring项目。

看完深有感触,这话说的太对了!

 

在此总结一下Spring迁移为SpringBoot遇到的那些坑,供大家参考:

 

1.SpringBoot无法动态注入xml

什么是动态注入xml呢?公司之前的Spring项目中,用到了大量的xml配置文件;在启动时,传入main方法中的args[]参数的不同,会加载不同的xml文件。实现原理大致如下:

ApplicationContext applicationContext = new ClassPathXmlApplicationContext(args);

其中,applicationContext为Spring的bean工厂对象,args为String[]数组,其中保存一些xml的路径。

但是,在SpringBoot下,你会发现,你只能这样启动SpringBoot对象并获得bean工厂对象:

ConfigurableApplicationContext context = SpringApplication.run(test.class, args);

其中,test.class为当前类,args为传入main方法的args[]参数,但是这个args即使包含xml的路径,SpringBoot也不会帮你加载。

找来找去,SpringBoot要想加载xml文件,只能通过注解实现了。

@ImportResource(locations={"classpath*:/spring/a/mubiao1*/*.xml","classpath*:/spring/test.xml"})

但是,注解怎么可能实现动态加载xml呢?又不能配置变量。

将xml转换为java文件?能否动态加载先不说,之前的项目可是有几百个xml,每个xml中有大量的bean,全部转换耗时耗力。

 

最后,只能勉强用@ImportResource与*符号,将所有的xml全部加载进去了,没有实现根据传入的args选择不同的xml加载的方式。

 

2.SpringBoot的xml文件中想使用符号“${}”实现动态替换会报错

在spring项目中,在xml文件直接使用“${}”是没有问题的,例如:

<bean id="a" class="com.a" >
   <property name="username">
      <value>
         <![CDATA[         
              我的名字是${user}
         ]]>
      </value>
   </property>
</bean>

其中,${user}会在程序执行过程中,使用Template对象动态替换为map中相同键的值,例如:

String template = "我的名字是${user}";//这个String实际上从xml注入的对象获得的,为了简化就直接写了
Map<String, String> map = new HashMap();
map.put("user","小明");
StringWriter writer = new StringWriter();
new Template(null, new StringReader(template), new Configuration())
      .process(map, writer);
System.out.println(writer.toString());

这样就会输出"我的名字是小明",如何替换取决于map中对应键的值,实现了程序运行中的动态替换。

 

但是,在SpringBoot中,如果你在xml中还是这么写,就会报错了:

Could not resolve placeholder 'a' in value "我的名字是${user}"

这时,如果你在application.properties中增加一行,就可以执行了:

user=小明

为什么呢?因为SpringBoot发现时"${}"会进行替换,如果无法替换则报错。

但是,在properties中配置好,并不符合在程序运行中动态替换的结果。

这也是我很不能理解的地方,我在xml中都用了CDATA标签了,你还要给我替换,这让我怎么实现在程序运行中用Template动态替换呢?

没办法,毕竟还得用SpringBoot完成任务,最终使用了这个折中的方法:

我的名字是@###@{user}

自定义一个特殊符号"@###@",后续在程序中准备使用Template替换时,先将"@###@"替换为"$",之后就可以用Template正常替换了。虽然不美观,但是功能实现了。

----------------------------------------------------------

新想到的第1个坑的解决办法(暂时没有想到更好的方法):

原理:springboot启动命令可以加载指定的application-*.properties,而注解可以使用${}读取properties中的数据。

步骤:
1.创建几百个application-*.properties
2.springboot启动类中使用注解:
@ImportResource(locations = {"classpath*:/spring/${mymsg.fileFolder}/*.xml"})
3.某个properties中写,例如application-file1.properties中写(mymsg.fileFolder对应的value):
mymsg.fileFolder=FileFolder1
4.启动jar包时,不同场景用不同命令,例如(加载application-file1.properties):
java -jar test.jar --spring.profiles.active=file1

总结:
这样,根据启动参数不同,读取不同properties,就可以加载不同xml了。

posted @ 2018-12-03 19:09  codeToSuccess  阅读(239)  评论(0编辑  收藏  举报