最近一個新項目準備使用SpringBoot,因為SpringBoot開發配置簡單些。但由于公司部署流程的原因,測試和生產環境需要將代碼打成WAR包部署到Tomcat下,并且數據庫連接使用JNDI數據源方式配置Tomcat里面。
這種部署方式本沒有問題,但是在本地環境我們用main方式啟動的SpringBoot時就遇到問題,由于Tomcat是以內核的方式嵌入在SpringBoot里面的,那怎樣配置JNDI數據源呢?
SpringBoot里使用JNDI數據源很簡單,只需在application.properties 文件中配置一下就可以了,如:
# JNDI數據源。開發環境在代碼中配置,測試、生產在容器中配置。 spring.datasource.jndi-name=java:comp/env/jdbc/timcore/DefaultDS
測試和生成環境,以WAR包方式部署在Tomcat里的情況,需要在Tomcat的conf/context.xml文件添加配置,如:
name='jdbc/timcore/DefaultDS' url='jdbc:postgresql://30.31.0.14:7523/timc' type='javax.sql.DataSource' driverClassName='org.postgresql.Driver'
本地以main方式啟動的需要修改Tomcat內核,打開JNDI數據源,并配置。比如我們項目是dev環境才是Main方式啟動,則需要:
1,新增application-dev.properties 文件:
DataSource.jndiName=jdbc/timcore/DefaultDS DataSource.auth=Container DataSource.driverClassName=org.postgresql.Driver DataSource.url=jdbc:postgresql://30.31.0.14:7523/timc DataSource.username=timcopr
2,創建一個PropConfig類,接收配置:
@ConfigurationProperties(prefix = 'DataSource') public class DataSourcePropConfig { private String driverClassName; private String maxActive;
3,代碼的方式修改配置,加入數據源:
public class MyWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter { private DataSourcePropConfig dataSourcePropConfig; // 開發環境手工添加數據源。測試、生產環境部署在容器中,在容器中配置數據源。 @ConditionalOnProperty(name = 'spring.profiles.active', havingValue = 'dev') public TomcatEmbeddedServletContainerFactory servletContainerFactory() { return new TomcatEmbeddedServletContainerFactory() { protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(Tomcat tomcat) { tomcat.enableNaming(); // 打開JNDI數據源 return super.getTomcatEmbeddedServletContainer(tomcat); protected void postProcessContext(Context context) { ContextResource resource = new ContextResource(); resource.setType(DataSource.class.getName()); resource.setName(dataSourcePropConfig.getJndiName()); resource.setAuth(dataSourcePropConfig.getAuth()); resource.setProperty('driverClassName', dataSourcePropConfig.getDriverClassName()); resource.setProperty('url', dataSourcePropConfig.getUrl()); resource.setProperty('username', dataSourcePropConfig.getUsername()); resource.setProperty('password', dataSourcePropConfig.getPwd()); resource.setProperty('maxActive', dataSourcePropConfig.getMaxActive()); // 最大連接數 resource.setProperty('maxIdle', dataSourcePropConfig.getMaxIdle()); // 空閑連接數 resource.setProperty('maxWait', dataSourcePropConfig.getMaxWait()); // 最大等待時間 context.getNamingResources().addResource(resource);
這樣同一份代碼就可以兼容兩種方式了。
|