Jak korzystać z JNDI DataSource dostarczonego przez Tomcat na wiosnę?

159

Mówi się, że w artykule Spring javadoc o DriverManagerDataSourceclass, ta klasa jest bardzo prosta i jest zalecana

aby użyć JNDI DataSource dostarczonego przez kontener. Taki element DataSourcemoże zostać ujawniony jako DataSourcefasola w Spring ApplicationContext za pośrednictwemJndiObjectFactoryBean

Pytanie brzmi: jak to osiągnąć?

Na przykład, jeśli chcę, aby DataSourcefasola miała dostęp do mojej niestandardowej bazy danych MySQL, czego będę wtedy potrzebować? Co mam napisać w konfiguracji kontekstu itp.?

Suzan Cioc
źródło

Odpowiedzi:

302

Jeśli używasz konfiguracji Springa opartej na schemacie XML, ustaw ją w kontekście Spring w następujący sposób:

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

Alternatywnie, użyj prostej konfiguracji bean, takiej jak ta:

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

Możesz zadeklarować zasób JNDI w pliku server.xml Tomcat, używając czegoś takiego:

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

I odwołaj się do zasobu JNDI z pliku kontekstowego.xml serwera Tomcat w następujący sposób:

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

Dokumentacja referencyjna:

Edycja: ta odpowiedź została zaktualizowana dla Tomcat 8 i Spring 4. Wprowadzono kilka zmian nazw właściwości dla domyślnej konfiguracji puli zasobów źródła danych Tomcat .

kaliatech
źródło
@skaffman Tak, ale podajesz link do dokumentacji referencyjnej Spring.
Etienne Miret
jaki plik dokładnie rozumiesz przez „kontekst sieciowy Tomcata.xml”?
Pavel Niedoba
1
@PavelNiedoba Tomcat używa „kontekstu” dla specyficznej konfiguracji aplikacji internetowej Tomcat. Plik kontekstu i / lub konfigurację kontekstu można umieścić w różnych lokalizacjach, więc nie mogę udzielić ostatecznej odpowiedzi. Typową lokalizacją jest „/META-INF/context.xml”. Zobacz sekcję „Definiowanie kontekstu” tutaj: tomcat.apache.org/tomcat-8.0-doc/config/…
kaliatech
Mmm ... wygląda na to, że nie działa dla mojej bazy danych Oracle, jakieś różnice z postgresql?
Phate
1
@Phate Na poziomie JDBC / JNDI / Tomcat nie ma fundamentalnych różnic między Oracle a PostgreSQL. Jednak Oracle bardzo różni się od PostgreSQL, jeśli chodzi o szczegóły konfiguracji klienta / serwera Oracle. Poza zakresem oryginalnego pytania / odpowiedzi. Zaproponuj opublikowanie nowego pytania ze szczegółami wypróbowanych rozwiązań, konkretnymi wersjami i wszelkimi komunikatami o błędach. Przykład: stackoverflow.com/questions/10388137/…
kaliatech
52

Dzięki mechanizmowi JavaConfig Springa możesz to zrobić w następujący sposób:

@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
źródło
2
Lub skorzystaj z bardziej wyspecjalizowanego JndiDataSourceLookup
Arend v. Reinersdorff
21

Zakładając, że w konfiguracji tomcat istnieje definicja źródła danych „sampleDS”, możesz dodać następujące wiersze do swojego, applicationContext.xmlaby uzyskać dostęp do źródła danych za pomocą JNDI.

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

Musisz zdefiniować przestrzeń nazw i lokalizację schematu dla jeeprefiksu za pomocą:

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
źródło
15

Dokumentacja: C.2.3.1 <jee:jndi-lookup/>(prosta)

Przykład:

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

Musisz tylko dowiedzieć się, z jaką nazwą JNDI serwer aplikacji powiązał źródło danych. Jest to całkowicie zależne od serwera, zapoznaj się z dokumentacją na serwerze, aby dowiedzieć się, jak to zrobić.

Pamiętaj, aby zadeklarować jeeprzestrzeń nazw na początku pliku bean, jak opisano w C.2.3 Schemat jee .

skaffman
źródło
8

Inna funkcja: zamiast server.xml, możesz dodać tag „Resource” w
your_application / META-INF / Context.xml (zgodnie z dokumentacją tomcat ) w następujący sposób:

<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
źródło
5

Zgodnie ze stroną HOW-TO serwera Apache Tomcat 7 JNDI Datasource musi istnieć konfiguracja zasobów w pliku 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>

To działa dla mnie

Antonio
źródło
4

Na swoich wiosennych zajęciach możesz wstrzyknąć fasolkę z adnotacją jak

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

i dodajesz to w swoim context.xml

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

Możesz zadeklarować zasób JNDI w pliku server.xml Tomcat za pomocą

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

powrót do context.xml de spring dodaj to

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

jeśli, tak jak w tym przykładzie, wstrzykujesz połączenie do bazy danych, upewnij się, że jar MySQL znajduje się w katalogu tomcat lib, w przeciwnym razie tomcat nie będzie w stanie utworzyć puli połączeń bazy danych MySQL.

Toumi
źródło
1

To rozwiązanie okazało się bardzo pomocne w przejrzystym sposobie całkowitego usunięcia konfiguracji XML.

Proszę sprawdzić tę konfigurację bazy danych za pomocą JNDI i struktury Spring. http://www.unotions.com/design/how-to-create-oracleothersql-db-configuration-using-spring-and-maven/

W tym artykule wyjaśniono, jak łatwo utworzyć konfigurację bazy danych w oparciu o konfigurację bazy danych jndi (db / test). Po zakończeniu konfiguracji wszystkie repozytoria bazy danych są ładowane przy użyciu tego jndi. Znalazłem przydatne. Jeśli @Pierre ma z tym problem, daj mi znać. To kompletne rozwiązanie do pisania konfiguracji bazy danych.

user3892286
źródło
W tym artykule wyjaśniono, jak łatwo utworzyć konfigurację bazy danych w oparciu o konfigurację bazy danych jndi (db / test). Po zakończeniu konfiguracji wszystkie repozytoria bazy danych są ładowane przy użyciu tego jndi. Znalazłem przydatne. Jeśli @Pierre ma z tym problem, daj mi znać. To kompletne rozwiązanie do pisania konfiguracji bazy danych.
user3892286
W tym artykule wyjaśniono, jak łatwo utworzyć konfigurację bazy danych w oparciu o konfigurację bazy danych jndi (db / test). Po zakończeniu konfiguracji wszystkie repozytoria bazy danych są ładowane przy użyciu tego jndi. Znalazłem przydatne. Jeśli @Pierre ma z tym problem, daj mi znać. To kompletne rozwiązanie do pisania konfiguracji bazy danych.
Sergio A.