springboot內置tomcat集成jndi多數據源


一,什么是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數據源請參考

https://www.cnblogs.com/springboot-wuqian/archive/2004/01/13/9418180.html

https://www.java4s.com/spring-boot-tutorials/spring-boot-configure-datasource-using-jndi-with-example/

https://cnsyear.com/posts/9b26f7c2.html

https://cnsyear.com/posts/ceb1797.html

但今天的重點是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

更改yml配置的jndi數據源名稱為MySecondMySql,重啟項目,訪問接口http://localhost:8080/getList

三,總結

以下幾種情況分別集成jndi數據源區別還是很大的,多注意一下!

1,spring外部容器集成jndi

2,springboot外部容器集成jndi

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

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

詳情參考

https://www.cnblogs.com/springboot-wuqian/archive/2004/01/13/9540439.html

就到這里了,再見!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM