背景
springboot憑借其高度的封裝性,極大地簡化了我們的開發。對於單體項目,為了提高后期線上的運維效率我們通常選擇采用war包的方式進行部署。當遇到多給項目,為了實現統一的數據源管理,我們公司將多個項目的數據源都配置在tomcat的配置文件里以實現數據源的統一管理。那么對於springboot這樣高度集成的項目,該如何實現讀取外部tomcat的數據源功能呢?
springboot項目打war包
pom文件
<groupId>com.ai</groupId>
<artifactId>ORCA</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>ORCA</name>
<!-- 設置打包方式為war -->
<packaging>war</packaging>
<description>虎鯨</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- 排除springboot自帶tomcat -->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
修改啟動類
public class Application extends SpringBootServletInitializer {
// 修改啟動類,繼承 SpringBootServletInitializer 並重寫 configure 方法
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
設置springboot讀取外部Tomcat數據源
思路
其實思路很簡單,主要便是拒絕讓spring加載默認的數據源,采用自己配置的方式從tomcat中獲取數據源,下面是具體的步驟:
實現
配置文件指定spring數據源為采用JNDI獲取數據源
#這里的name很重要,在tomcat里需要指定相同名稱的resource
spring.datasource.jndi-name=java:comp/env/jdbc/myDs
spring.datasource.expected-type = javax.sql.DataSource
spring.datasource.driver-class-name = com.mysql.jdbc.Driver
新建配置,自己配置DataSource
package com.ai.configs;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jndi.JndiObjectFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import javax.naming.NamingException;
import javax.sql.DataSource;
@Configuration //注冊到springboot 容器中
@MapperScan(basePackages = "com.ai.dao",sqlSessionTemplateRef = "test1SqlSessionTemplate")
public class DataSource1Config {
//application.properties中的jndi名稱
@Value("${spring.datasource.jndi-name}")
private String jndiName;
@Bean(name = "test1DataSource",destroyMethod = "") // destroy method is disabled for Weblogic update app ability
@ConfigurationProperties(prefix = "spring.datasource.bigdata")
public DataSource bigdataDs() throws NamingException {
JndiObjectFactoryBean bean=new JndiObjectFactoryBean();
bean.setJndiName(jndiName);
bean.setProxyInterface(DataSource.class);
bean.setLookupOnStartup(false);
bean.afterPropertiesSet();
return (DataSource) bean.getObject();
}
@Bean(name = "test1SqlSessionFactory")
public SqlSessionFactory testSqlSessionFactory(@Qualifier("test1DataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
//加載其他文件,如mapper.xml
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));
return bean.getObject();
}
//事務管理
@Bean(name = "test1TransactionManager")
public DataSourceTransactionManager testTransactionManager(@Qualifier("test1DataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "test1SqlSessionTemplate")
public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("test1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
tomcat配置
在tomcat server.xml中添加如下配置
<GlobalNamingResources>
<!-- Editable user database that can also be used by
UserDatabaseRealm to authenticate users
-->
<Resource auth="Container" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" name="UserDatabase" pathname="conf/tomcat-users.xml" type="org.apache.catalina.UserDatabase"/>
<!-- 這個resource是要添加的內容 -->
<Resource name="jdbc/myDs" auth="Container"
type="javax.sql.DataSource"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://url:3306/db_name?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&failOverReadOnly=false"
username="root"
password="password"
initialSize="50"
maxTotal="50"
maxIdle="30"
maxWaitMillis="60000"
testOnBorrow="true"
validationQuery="select 1"
/>
</GlobalNamingResources>