Làm cách nào để sử dụng JNDI DataSource được cung cấp bởi Tomcat trong Spring?


159

Người ta nói rằng trong bài viết Spring javadoc về DriverManagerDataSourcelớp, lớp này rất đơn giản và nó được khuyến khích

để sử dụng JNDI DataSource được cung cấp bởi container. Như vậy DataSourcecó thể được hiển thị như một DataSourcebean trong Spring ApplicationContext thông quaJndiObjectFactoryBean

Câu hỏi là: làm thế nào để tôi thực hiện điều này?

Ví dụ, nếu tôi muốn có DataSourcebean để truy cập cơ sở dữ liệu MySQL tùy chỉnh của mình, tôi sẽ yêu cầu gì sau đó? Tôi nên viết gì trong cấu hình bối cảnh, vv?

Câu trả lời:


302

Nếu sử dụng cấu hình dựa trên lược đồ XML của Spring, hãy thiết lập trong bối cảnh Spring như thế này:

<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:jee="http://www.springframework.org/schema/jee" xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd">
...
<jee:jndi-lookup id="dbDataSource"
   jndi-name="jdbc/DatabaseName"
   expected-type="javax.sql.DataSource" />

Ngoài ra, thiết lập bằng cách sử dụng cấu hình bean đơn giản như thế này:

<bean id="DatabaseName" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="java:comp/env/jdbc/DatabaseName"/>
</bean>

Bạn có thể khai báo tài nguyên JNDI trong máy chủ của tomcat bằng cách sử dụng cái gì đó như thế này:

<GlobalNamingResources>
    <Resource name="jdbc/DatabaseName"
              auth="Container"
              type="javax.sql.DataSource"
              username="dbUser"
              password="dbPassword"
              url="jdbc:postgresql://localhost/dbname"
              driverClassName="org.postgresql.Driver"
              initialSize="20"
              maxWaitMillis="15000"
              maxTotal="75"
              maxIdle="20"
              maxAge="7200000"
              testOnBorrow="true"
              validationQuery="select 1"
              />
</GlobalNamingResources>

Và tham khảo tài nguyên JNDI từ bối cảnh web của Tomcat như thế này:

  <ResourceLink name="jdbc/DatabaseName"
   global="jdbc/DatabaseName"
   type="javax.sql.DataSource"/>

Tài liệu tham khảo:

Chỉnh sửa: Câu trả lời này đã được cập nhật cho Tomcat 8 và Spring 4. Đã có một vài thay đổi tên thuộc tính cho thiết lập nhóm tài nguyên nguồn dữ liệu mặc định của Tomcat .


@skaffman Có, nhưng bạn cung cấp một liên kết đến tài liệu tham khảo Spring.
Etienne Miret

Tập tin chính xác của bạn có nghĩa là gì bởi "Tomcat's web bối cảnh"?
Pavel Niedoba

1
@PavelNiedoba Tomcat sử dụng "bối cảnh" cho cấu hình ứng dụng web cụ thể của tomcat. Tệp ngữ cảnh và / hoặc cấu hình bối cảnh có thể được đặt ở nhiều vị trí khác nhau, vì vậy tôi không thể đưa ra câu trả lời dứt khoát cho bạn. Một vị trí phổ biến là "/META-INF/context.xml". Xem phần "Xác định bối cảnh" tại đây: tomcat.apache.org/tomcat-8.0-doc/config/ mẹo
kaliatech

Mmm ... dường như không hoạt động cho db tiên tri của tôi, có sự khác biệt nào với postgresql không?
Phate

1
@Phate Không có sự khác biệt cơ bản nào với Oracle so với PostgreSQL ở cấp độ JDBC / JNDI / Tomcat. Tuy nhiên, Oracle rất khác với PostgreSQL khi nói về chi tiết thiết lập máy khách / máy chủ của Oracle. Phạm vi bên ngoài của câu hỏi / câu trả lời ban đầu. Đề nghị đăng một câu hỏi mới với chi tiết về những gì bạn đã thử, các phiên bản cụ thể và bất kỳ thông báo lỗi nào. Ví dụ: stackoverflow.com/questions/10388137/ từ
kaliatech

52

Với cơ chế JavaConfig của Spring, bạn có thể làm như vậy:

@Configuration
public class MainConfig {

    ...

    @Bean
    DataSource dataSource() {
        DataSource dataSource = null;
        JndiTemplate jndi = new JndiTemplate();
        try {
            dataSource = jndi.lookup("java:comp/env/jdbc/yourname", DataSource.class);
        } catch (NamingException e) {
            logger.error("NamingException for java:comp/env/jdbc/yourname", e);
        }
        return dataSource;
    }

}


21

Giả sử bạn có định nghĩa nguồn dữ liệu "sampleDS" bên trong cấu hình tomcat của mình, bạn có thể thêm các dòng sau vào applicationContext.xmlđể truy cập nguồn dữ liệu bằng JNDI.

<jee:jndi-lookup expected-type="javax.sql.DataSource" id="springBeanIdForSampleDS" jndi-name="sampleDS"/>

Bạn phải xác định không gian tên và vị trí lược đồ cho jeetiền tố bằng cách sử dụng:

xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd"

15

Tài liệu: C.2.3.1 <jee:jndi-lookup/>(đơn giản)

Thí dụ:

<jee:jndi-lookup id="dataSource" jndi-name="jdbc/MyDataSource"/>

Bạn chỉ cần tìm ra tên JNDI mà máy chủ ứng dụng của bạn đã ràng buộc nguồn dữ liệu. Điều này là hoàn toàn dành riêng cho máy chủ, tham khảo tài liệu trên máy chủ của bạn để tìm hiểu làm thế nào.

Hãy nhớ khai báo jeekhông gian tên ở đầu tệp đậu của bạn, như được mô tả trong C.2.3 Lược đồ jee .


8

Một tính năng khác: thay vì server.xml, bạn có thể thêm thẻ "Tài nguyên" trong
your_application / META-INF / Context.xml (theo tài liệu tomcat ) như thế này:

<Context>
<Resource name="jdbc/DatabaseName" auth="Container" type="javax.sql.DataSource"
  username="dbUsername" password="dbPasswd"
  url="jdbc:postgresql://localhost/dbname"
  driverClassName="org.postgresql.Driver"
  initialSize="5" maxWait="5000"
  maxActive="120" maxIdle="5"
  validationQuery="select 1"
  poolPreparedStatements="true"/>
</Context>

5

Theo trang Apache Tomcat 7 JNDI Datasource phải có cấu hình tài nguyên trong web.xml:

<resource-ref>
  <description>DB Connection</description>
  <res-ref-name>jdbc/TestDB</res-ref-name>
  <res-type>javax.sql.DataSource</res-type>
  <res-auth>Container</res-auth>

Nó ổn với tôi


4

Trong lớp học mùa xuân của bạn, Bạn có thể tiêm một hạt đậu có chú thích như

@Autowired
@Qualifier("dbDataSource")
private DataSource dataSource;

và Bạn thêm phần này vào ngữ cảnh của bạn

<beans:bean id="dbDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <beans:property name="jndiName" value="java:comp/env/jdbc/MyLocalDB"/>
</beans:bean>

Bạn có thể khai báo tài nguyên JNDI trong máy chủ của tomcat bằng cách sử dụng

<Resource name="jdbc/TestDB" 
  global="jdbc/TestDB" 
  auth="Container" 
  type="javax.sql.DataSource" 
  driverClassName="com.mysql.jdbc.Driver" 
  url="jdbc:mysql://localhost:3306/TestDB" 
  username="pankaj" 
  password="pankaj123" 

  maxActive="100" 
  maxIdle="20" 
  minIdle="5" 
  maxWait="10000"/>

quay lại bối cảnh mùa xuân de mùa xuân thêm điều này

<ResourceLink name="jdbc/MyLocalDB"
                global="jdbc/TestDB"
                auth="Container"
                type="javax.sql.DataSource" />

nếu, giống như exmple này bạn đang tiêm kết nối vào cơ sở dữ liệu, hãy đảm bảo rằng jar MySQL có trong thư mục lib tomcat, nếu không tomcat sẽ không thể tạo nhóm kết nối cơ sở dữ liệu MySQL.


1

Tôi thấy giải pháp này rất hữu ích theo cách sạch để loại bỏ hoàn toàn cấu hình xml.

Vui lòng kiểm tra cấu hình db này bằng JNDI và khung mùa xuân. http://www.unferences.com/design/how-to-create-oracleothersql-db-configuration-USE-spring-and-maven/

Trong bài viết này, nó giải thích cách dễ dàng tạo ra một sự kết hợp db dựa trên cấu hình cơ sở dữ liệu jndi (db / test). một khi bạn đã hoàn tất cấu hình thì tất cả các kho lưu trữ db được tải bằng jndi này. Tôi đã tìm thấy hữu ích. Nếu @Pierre có vấn đề với điều này thì hãy cho tôi biết. Đó là giải pháp hoàn chỉnh để viết cấu hình db.


bởi bài viết này, nó giải thích cách dễ dàng tạo một phân phối db dựa trên cấu hình cơ sở dữ liệu jndi (db / test). một khi bạn đã hoàn tất cấu hình thì tất cả các kho lưu trữ db được tải bằng jndi này. Tôi đã tìm thấy hữu ích. Nếu @Pierre có vấn đề với điều này thì hãy cho tôi biết. Đó là giải pháp hoàn chỉnh để viết cấu hình db.
dùng3892286

bởi bài viết này, nó giải thích cách dễ dàng tạo một phân phối db dựa trên cấu hình cơ sở dữ liệu jndi (db / test). một khi bạn đã hoàn tất cấu hình thì tất cả các kho lưu trữ db được tải bằng jndi này. Tôi đã tìm thấy hữu ích. Nếu @Pierre có vấn đề với điều này thì hãy cho tôi biết. Đó là giải pháp hoàn chỉnh để viết cấu hình db.
Sergio A.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.