背景
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>