背景

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&amp;characterEncoding=utf-8&amp;autoReconnect=true&amp;failOverReadOnly=false" 
              username="root"
              password="password"
              initialSize="50"
              maxTotal="50"
              maxIdle="30"
              maxWaitMillis="60000"
              testOnBorrow="true"
              validationQuery="select 1"
              />
  </GlobalNamingResources>

到这里就已经完成了该功能

posted on 2020-07-17 10:41  yonyong  阅读(3710)  评论(0编辑  收藏  举报