Bagaimana cara menggunakan JNDI DataSource yang disediakan oleh Tomcat di Spring?

159

Dikatakan bahwa dalam artikel javadoc Spring tentang DriverManagerDataSourcekelas, bahwa kelas ini sangat sederhana dan direkomendasikan

untuk menggunakan JNDI DataSource yang disediakan oleh wadah. Seperti DataSourcedapat diekspos sebagai DataSourcekacang dalam konteks Application Spring melaluiJndiObjectFactoryBean

Pertanyaannya adalah: bagaimana saya mencapai ini?

Misalnya, jika saya ingin memiliki DataSourcekacang untuk mengakses database MySQL kustom saya, apa yang akan saya perlukan? Apa yang harus saya tulis dalam konfigurasi konteks, dll?

Suzan Cioc
sumber

Jawaban:

302

Jika menggunakan konfigurasi berbasis skema Spring, setup dalam konteks Spring seperti ini:

<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" />

Atau, setup menggunakan konfigurasi kacang sederhana seperti ini:

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

Anda dapat mendeklarasikan sumber daya JNDI di server tomcat.xml menggunakan sesuatu seperti ini:

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

Dan referensi sumber daya JNDI dari konteks web Tomcat.xml seperti ini:

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

Dokumentasi rujukan:

Sunting: Jawaban ini telah diperbarui untuk Tomcat 8 dan Spring 4. Ada beberapa perubahan nama properti untuk penyiapan kumpulan sumber data sumber default Tomcat .

Kaliatech
sumber
@skaffman Ya, tetapi Anda memberikan tautan ke dokumentasi referensi Spring.
Etienne Miret
file apa yang Anda maksud dengan "Tomcat's web context.xml"?
Pavel Niedoba
1
@PavelNiedoba Tomcat menggunakan "konteks" untuk konfigurasi aplikasi web spesifik Tomcat. File konteks dan / atau konfigurasi konteks dapat ditempatkan di berbagai lokasi, jadi saya tidak bisa memberikan jawaban yang pasti. Lokasi umum adalah "/META-INF/context.xml". Lihat "Mendefinisikan konteks" bagian di sini: tomcat.apache.org/tomcat-8.0-doc/config/...
kaliatech
Mmm ... sepertinya tidak berfungsi untuk oracle db saya, ada perbedaan dengan postgresql?
Phate
1
@Phate Tidak ada perbedaan mendasar dengan Oracle vs PostgreSQL di tingkat JDBC / JNDI / Tomcat. Namun, Oracle sangat berbeda dari PostgreSQL dalam hal detail pengaturan klien / server Oracle. Di luar ruang lingkup pertanyaan / jawaban asli. Sarankan posting pertanyaan baru dengan perincian tentang apa yang telah Anda coba, versi spesifik, dan pesan kesalahan apa pun. Contoh: stackoverflow.com/questions/10388137/…
kaliatech
52

Dengan mekanisme JavaConfig Spring, Anda dapat melakukannya seperti:

@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;
    }

}
Abdull
sumber
2
Atau gunakan JndiDataSourceLookup yang
Arend v. Reinersdorff
21

Dengan asumsi Anda memiliki definisi sumber data "sampleDS" di dalam konfigurasi kucing jantan, Anda dapat menambahkan baris-baris berikut applicationContext.xmluntuk mengakses sumber data menggunakan JNDI.

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

Anda harus menentukan lokasi namespace dan skema untuk jeeawalan menggunakan:

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"
melihcelik
sumber
15

Dokumentasi: C.2.3.1 <jee:jndi-lookup/>(sederhana)

Contoh:

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

Anda hanya perlu mencari tahu apa nama JNDI yang digunakan oleh server aplikasi Anda. Ini sepenuhnya khusus untuk server, lihat dokumen di server Anda untuk mengetahui caranya.

Ingatlah untuk mendeklarasikan jeenamespace di bagian atas file kacang Anda, seperti yang dijelaskan dalam C.2.3 Skema jee .

skaffman
sumber
8

Fitur lain: alih-alih server.xml, Anda dapat menambahkan tag "Resource" di
aplikasi_anda / META-INF / Context.xml (sesuai dengan dokumen kucing jantan ) seperti ini:

<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>
Evgen
sumber
5

Menurut halaman Apache Tomcat 7 JNDI Datasource BAGAIMANA harus ada konfigurasi sumber daya di 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>

Itu bekerja untuk saya

Antonio
sumber
4

Di kelas musim semi Anda, Anda bisa menyuntikkan kacang beranotasi seperti

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

dan Anda menambahkan ini di context.xml Anda

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

Anda dapat mendeklarasikan sumber daya JNDI di tomcat's server.xml menggunakan

<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"/>

kembali ke context.xml de spring tambahkan ini

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

jika, seperti contoh ini Anda menyuntikkan koneksi ke database, pastikan bahwa toples MySQL ada di direktori tomcat lib, jika tidak tomcat tidak akan dapat membuat kumpulan koneksi database MySQL.

Toumi
sumber
1

Saya menemukan solusi ini sangat membantu dalam cara yang bersih untuk menghapus konfigurasi xml sepenuhnya.

Silakan periksa konfigurasi db ini menggunakan JNDI dan kerangka kerja pegas. http://www.unotions.com/design/how-to-create-oracleothersql-db-configuration-using-spring-and-maven/

Pada artikel ini, dijelaskan bagaimana mudahnya membuat konfigurasi db berdasarkan konfigurasi database jndi (db / test). setelah Anda selesai dengan konfigurasi maka semua repositori db diambil menggunakan jndi ini. Saya menemukan berguna. Jika @Pierre memiliki masalah dengan ini, beri tahu saya. Ini solusi lengkap untuk menulis konfigurasi db.

pengguna3892286
sumber
pada artikel ini, dijelaskan bagaimana mudahnya membuat konfigurasi db berdasarkan konfigurasi database jndi (db / test). setelah Anda selesai dengan konfigurasi maka semua repositori db diambil menggunakan jndi ini. Saya menemukan berguna. Jika @Pierre memiliki masalah dengan ini, beri tahu saya. Ini solusi lengkap untuk menulis konfigurasi db.
user3892286
pada artikel ini, dijelaskan bagaimana mudahnya membuat konfigurasi db berdasarkan konfigurasi database jndi (db / test). setelah Anda selesai dengan konfigurasi maka semua repositori db diambil menggunakan jndi ini. Saya menemukan berguna. Jika @Pierre memiliki masalah dengan ini, beri tahu saya. Ini solusi lengkap untuk menulis konfigurasi db.
Sergio A.