spring boot 2.0已经正式发布了,相比spring boot 1.x有了很多的改变,具体有哪些改变内容我就不详细介绍了,我这里就介绍一下我这边的spring boot 1.5.9版本升级到spring boot 2.0所需要做的修改吧。
我这里主要有以下几方面的内容
1、对内置的tomcat做了自定义
2、用了spring data jpa
目前我这里遇到的就是这两方面的内容导致应用无法启动,今天花了一点时间来把问题解决了使应用能顺利启动起来。
我这里主要是需要在开发测试的时候内置tomcat需要支持多域名所以做了一些自定义,直接看代码
spring boot 1.x
package com.spring.config.tomcat;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.core.StandardHost;
import org.apache.catalina.startup.Tomcat;
import org.springframework.boot.context.embedded.EmbeddedServletContainer;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import java.io.File;
/**
* com.spring.config.tomcat
* @author jackycheng
* 2017/10/18
*
* 扩展内置tomcat,添加自定义域名以及多域名支持
*
**/
public class Myp2cTomcatEmbeddedServletContainerFactory extends TomcatEmbeddedServletContainerFactory {
@Override
public EmbeddedServletContainer getEmbeddedServletContainer(ServletContextInitializer... initializers) {
Tomcat tomcat = new Tomcat();
File baseDir = (createTempDir("tomcat"));
tomcat.setBaseDir(baseDir.getAbsolutePath());
tomcat.setHostname("sso.myp2c.me");
StandardHost host=(StandardHost)tomcat.getHost();
if(host!=null){
host.addAlias("sso1.myp2c.me");
host.addAlias("sso2.myp2c.me");
tomcat.setHost(host);
}
tomcat.getHost().setAutoDeploy(false);
tomcat.getEngine().setBackgroundProcessorDelay(-1);
for (Connector additionalConnector : super.getAdditionalTomcatConnectors()) {
tomcat.getService().addConnector(additionalConnector);
}
prepareContext(tomcat.getHost(), initializers);
return getTomcatEmbeddedServletContainer(tomcat);
}
}
我们是通过继承自TomcatEmbeddedServletContainerFactory来完成自定义的,但是在spring boot 2.0中已经没有这个类了,因为spring boot团队把所以web相关的内容都统一到了org.springframework.boot.web这个包里面了,这个包里面包含所有内置web容器的内容,我们看看修改后的适配spring boot 2.0的内置tomcat自定义代码
package com.hw.config.tomcat;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.core.StandardHost;
import org.apache.catalina.startup.Tomcat;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServer;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import java.io.File;
/**
* @author chengjian
* @date 2018/3/27
**/
public class Myp2cTomcatCustomizationBean extends TomcatServletWebServerFactory{
@Override
public WebServer getWebServer(ServletContextInitializer... initializers) {
Tomcat tomcat = new Tomcat();
File baseDir = (createTempDir("tomcat"));
tomcat.setBaseDir(baseDir.getAbsolutePath());
tomcat.setHostname("sso.myp2c.me");
StandardHost host=(StandardHost)tomcat.getHost();
if(host!=null){
host.addAlias("sso1.myp2c.me");
host.addAlias("sso2.myp2c.me");
tomcat.setHost(host);
}
tomcat.getHost().setAutoDeploy(false);
tomcat.getEngine().setBackgroundProcessorDelay(-1);
for (Connector additionalConnector : super.getAdditionalTomcatConnectors()) {
tomcat.getService().addConnector(additionalConnector);
}
prepareContext(tomcat.getHost(), initializers);
return getTomcatWebServer(tomcat);
}
}
我们是继承自TomcatServletWebServerFactory这个类了,其实对比源代码发现这两个类其实没有多大差别的,修改好了内置tomcat启动就没有问题了
个人理解spring boot 2.0 主要是利用了jdk 8以上提供的各种新的功能重新进行设计和封装。
spring data jpa也是需要修改一些配置应用才能启动起来。
1.我们需要修改我们的RepositoryConfig中关于Hibernate的propertites配置
spring boot 1.x
/**
* 通过jpaProperties指定hibernate数据库方言以及在控制台打印sql语句
* @param dataSource
* @return
*/
private Map getVendorProperties(DataSource dataSource) {
Map map = jpaProperties.getHibernateProperties(dataSource);
map.put("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
map.put("hibernate.show_sql", "true");
return map;
}
spring boot 2.0
/**
* 通过jpaProperties指定hibernate数据库方言以及在控制台打印sql语句
* @return
*/
private Map getVendorProperties() {
Map map = jpaProperties.getHibernateProperties(new HibernateSettings());
map.put("hibernate.dialect", "org.hibernate.dialect.SQLServer2008Dialect");
map.put("hibernate.show_sql", "true");
return map;
}
对比一下jpaProperties.getHibernateProperties方法的参数发生了变化由过去的数据源变为了HibernateSettings了。
2.修改dao层的相关方法
spring boot 2.0中关于查找某个实体的方法发生了变化
在spring boot 1.x中
/**
* Retrieves an entity by its id.
*
* @param id must not be {@literal null}.
* @return the entity with the given id or {@literal null} if none found
* @throws IllegalArgumentException if {@code id} is {@literal null}
*/
T findOne(ID id);
但是在spring boot 2.0中
/**
* Retrieves an entity by its id.
*
* @param id must not be {@literal null}.
* @return the entity with the given id or {@literal Optional#empty()} if none found
* @throws IllegalArgumentException if {@code id} is {@literal null}.
*/
Optional findById(ID id);
同时返回的类型也有变化,在1.x版本的时候直接返回的是泛型封装类型T,但是在2.0以后返回的是Optional了,这是jdk 8出来的新特性,用于对实体为空的处理,所以spring boot 2.0才需要jdk 8以上版本。
这里我们就需要针对Optional进行处理了
我们不需要判断null了我们可以通过Optional提供的
public boolean isPresent()
Return true if there is a value present, otherwise false.
方法来进行判断最后再通过
public T get()
If a value is present in this Optional, returns the value, otherwise throws NoSuchElementException.
Returns:
the non-null value held by this Optional
Throws:
NoSuchElementException - if there is no value present
来获取我们想要的对象了
针对我的应用我做了以下配置修改应用就启动起来了,用了spring提供的其他模块如果应用还是没发启动请参见spring官方文档。