一,什么是JNDI数据源?


我们看下百度百科的描述

JNDI(Java Naming and Directory Interface,Java命名和目录接口)是SUN公司提供的一种标准的Java命名系统接口,JNDI提供统一的客户端API,通过不同的访问提供者接口JNDI服务供应接口(SPI)的实现,由管理者将JNDI API映射为特定的命名服务和目录系统,使得Java应用程序可以和这些命名服务和目录服务之间进行交互。

看完了之后,是不是感觉很抽象?这里我们需要理解这么几点

(1)JNDI是J2EE的规范之一。

(2)JNDI主要有两部分组成:应用程序编程接口和服务供应商接口。应用程序编程接口提供了Java应用程序访问各种命名和目录服务的功能,服务供应商接口提供了任意一种服务的供应商使用的功能。

(3)J2EE 规范要求全部 J2EE 容器都要提供 JNDI 规范的实现。

(4)JNDI 提出的目的是为了解藕,避免了程序与数据库之间的紧耦合,使应用更加易于配置、易于部署。


以上概念内容摘抄自大佬博客,以下内容皆为笔者亲历亲为所得所感悟!

JNDI的出现,让数据库连接代码交给容器管理,比如Tomcat、JBOSS等容器,这样对于开发者就不用关心数据库配置是什么,使用的什么数据库驱动连接数据库等

传统的JNDI是依赖web容器的,例如spring框架,在容器中配置好数据源(或者多数据源)配置,然后在spring项目的配置文件中指定数据源名称,然后把spring项目打成war包部署到容器中运行,就可以使用JNDI数据源了!

spring项目外置tomcat集成jndi数据源请参考

但今天的重点是springboot集成jndi数据源,其实按道理来说,springboot使用的是内置tomcat,也应该可以集成jndi,结果是可以,不过真的走了很多弯路,跳了很多坑,今天就来给大家讲一下springboot内置tomcat如何集成jndi数据源!

二,springboot内置tomcat开始集成JNDI

1,添加依赖

环境所需依赖包括:mysql驱动,mybatis-starter

<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>

上面的依赖是必需的,连接和操作数据库少不了的,关键是下面的tomcat依赖,竟然卡了我一天,没有它还真不行,如果没有它的话,当你配置好了数据源信息并注入到spring容器中,会报错提示找不到数据源,亦或者是无法创建数据源

<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-dbcp</artifactId>
<version>${tomcat.version}</version>
</dependency>

2,启动类

需要在启动类上加一个注解

@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})

这个注解的作用是:在springboot启动并自动配置时排除自动配置数据源信息,排除之后,在application.yml或application.properties中即使没有配置dataSource仍正常运行,否则会因为自动配置了数据源而找不到数据源的配置报错!

上面的是同行们的经验!但是我发现,即使不配置好像也没关系!一脸懵逼

3,配置dataSource数据源信息

创建一个数据源配置类,配置数据源信息,多个数据源可以配置多个Resource

@Configuration
public class DBConfiguration {
@Bean
public ServletWebServerFactory servletContainer() {
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {
@Override
protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) {
tomcat.enableNaming();//启用默认禁用的JNDI命名
return super.getTomcatWebServer(tomcat);
}
@Override
protected void postProcessContext(Context context) {
//数据源 1
//构建一个ContextResource对象,然后添加到Context对象中
ContextResource resource = new ContextResource();
resource.setName("jdbc/MyFirstMySql");
resource.setType(DataSource.class.getName());
resource.setProperty("driverClassName", "com.mysql.cj.jdbc.Driver");
resource.setProperty("url", "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC");
resource.setProperty("username", "root");
resource.setProperty("password","1234");
context.getNamingResources().addResource(resource);
//数据源 2
//构建一个ContextResource对象,然后添加到Context对象中
ContextResource resource1 = new ContextResource();
resource1.setName("jdbc/MySecondMySql");
resource1.setType(DataSource.class.getName());
resource1.setProperty("driverClassName", "com.mysql.cj.jdbc.Driver");
resource1.setProperty("url", "jdbc:mysql://localhost:3306/guli?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC");
resource1.setProperty("username", "root");
resource1.setProperty("password","1234");
context.getNamingResources().addResource(resource1);
super.postProcessContext(context);
}
};
return tomcat;
}
}

4,配置yml文件

只需要在yml文件中指定要使用的数据源名称即可,其他的不需要配置

spring:
datasource:
jndi-name: jdbc/MySecondMySql

到这里其实集成jndi数据源就已经结束了,就可以使用了,下面来进行测试!

5,开始测试

创建mapper文件,并注入到ctrl中进行测试,运行项目访问

content这张表在上面的两个数据库中同时存在,不过在guli数据库中是多条数据,而在test数据库中是只有一条数据,这样可以区分开来看效果!

@Mapper
public interface TestMapper {
@Select(value = "select * from content")
List<Map> getList();
}
@Autowired
TestMapper testMapper;
@RequestMapping("/getList")
@ResponseBody
public List<Map> getList(){
return testMapper.getList();
}

首先更改yml配置的jndi数据源名称为MyFirstMySql,重启项目,访问接口http://localhost:8080/getList

springboot内置tomcat集成jndi多数据源_数据源

更改yml配置的jndi数据源名称为MySecondMySql,重启项目,访问接口http://localhost:8080/getList

springboot内置tomcat集成jndi多数据源_tomcat_02

三,总结

以下几种情况分别集成jndi数据源区别还是很大的,多注意一下!


1,spring外部容器集成jndi

2,springboot外部容器集成jndi

3,springboot1.X内部容器集成jndi

4,springboot2.X内部容器集成jndi


​​

就到这里了,再见!



作者:樊同学