Spring Boot Configure DataSource Using JNDI with Example

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

===========================================================================mysql

We already saw the default approach to configure datasource, in this article I am going to explain you how to configure datasources using JNDI lookup in spring boot applications.  Before you read this article, I highly recommend to read How to Deploy Spring Boot Applications on External Tomcat Server.web

 

Spring Boot : Steps to Configure JNDI DataSource with External Tomcat

  • Add a dependency to pom.xml to give support to our Spring Boot application to run on external servers and also add packaging war (I will explain this later 🙂 )
  • Extend main class with SpringBootServletInitializer and override its configure method
  • Add a property spring.datasource.jndi-name in application.properties
  • Create new folder webapp/META-INF under main and add context.xml (will see this later)
  • Generate a WAR and deploy into the external Tomcat Server, that’s it you are good to go 😉

Before all these, make sure you have datasource information in your external server’s server.xml 🙂 this is very very important. Add the below line in between <GlobalNamingResources/> tag.spring

<Resource auth="Container" driverClassName="com.mysql.jdbc.Driver" 
                           maxActive="20" 
                           maxIdle="0" 
                           maxWait="10000" 
                           name="jdbc/j4s" 
                           password="java4s" 
                           username="java4s"
                           type="javax.sql.DataSource" 
                           url="jdbc:mysql://localhost/test"/>

I have given my local details, just change accordingly, mainly you need to change usernamepasswordand url.sql

 

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.java4s</groupId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  <artifactId>SpringBootDataSourceConfigJNDILookUp</artifactId>
  
  	<parent>
	    <groupId>org.springframework.boot</groupId>
	    <artifactId>spring-boot-starter-parent</artifactId>
	    <version>1.5.6.RELEASE</version>
	</parent>
	
	<dependencies>
		<dependency>
	        <groupId>org.springframework.boot</groupId>
	        <artifactId>spring-boot-starter-web</artifactId>
	    </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>    
		<dependency>
		    <groupId>mysql</groupId>
		    <artifactId>mysql-connector-java</artifactId>
		</dependency>		
		<dependency>
		   <groupId>org.springframework.boot</groupId>
		   <artifactId>spring-boot-starter-tomcat</artifactId>
		   <scope>provided</scope>
		</dependency>
	</dependencies>

	<properties>
	 	<java.version>1.8</java.version>
	</properties>
	
</project>

SpringBootApp.java

package com.java4s.app;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;

@SpringBootApplication
public class SpringBootApp extends SpringBootServletInitializer {

	public static void main(String[] args) {
		SpringApplication.run(SpringBootApp.class, args);
	}
	
	@Override
	protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
		return application.sources(SpringBootApp.class);
	}
}

application.properties

spring.datasource.jndi-name=java:comp/env/jdbc/j4s

context.xml

<?xml version="1.0" encoding="UTF-8"?>
<context>
	<ResourceLink auth="Container" name="jdbc/j4s" global="jdbc/j4s" type="javax.sql.DataSource" />
</context>

Make sure value in global attribute should match with the name attribute’s value in server.xml’s Resource tag (read again if you didn’t understand 🙂 ), I hope you know the basic JNDI concept.apache

lets see other supporting files that I have used in this example.tomcat

SpringJava4sController.java

package com.java4s.app.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.java4s.app.repository.SpringJava4sDAO;
import com.java4s.model.Customer;

@RestController
public class SpringJava4sController {
	
	@Autowired
	public SpringJava4sDAO dao;
	
	@RequestMapping("/get-cust-info")
	public List<Customer> customerInformation() {
		
		List<Customer> customers = dao.isData();		 
		
		return customers;
	}
}

SpringJava4sDAO.java

package com.java4s.app.repository;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import com.java4s.model.Customer;

@Repository
public class SpringJava4sDAO {
	
	@Autowired
	private JdbcTemplate jdbcTemplate;
	
	private static final String SQL = "select * from customers";
	
	public List<Customer> isData() {
		
		List<Customer> customers = new ArrayList<Customer>();

		List<Map<String, Object>> rows = jdbcTemplate.queryForList(SQL);
		
		for (Map<String, Object> row : rows) {
			Customer customer = new Customer();
			
			customer.setCustNo((int)row.get("Cust_id"));
			customer.setCustName((String)row.get("Cust_name"));
			customer.setCountry((String)row.get("Country"));
			
			customers.add(customer);
		}

		return customers;
		
	}
}

Customer.java

package com.java4s.model;

public class Customer {
	
	private int custNo;
	private String custName;
	private String country;
	
	public Customer() {		
	}
	
	public Customer(int custNumber, String custName, String country) {
		this.custNo = custNumber;
		this.custName = custName;
		this.country = country;
	}

	public int getCustNo() {
		return custNo;
	}

	public void setCustNo(int custNo) {
		this.custNo = custNo;
	}

	public String getCustName() {
		return custName;
	}

	public void setCustName(String custName) {
		this.custName = custName;
	}

	public String getCountry() {
		return country;
	}

	public void setCountry(String country) {
		this.country = country;
	}	
}

Now just right click on the application > Run As > Maven install  ::. this will generate a WAR file in your applications target folder.  Now you can import that WAR and verify the changes.app

Output

You can download and play with the code 🙂webapp


 

Spring Boot : Steps to Configure JNDI DataSource with Embedded Tomcat

Lets compare the steps we have followed for the configuration done above for external tomcat server, for Embedded tomcat…maven

  • No need to add any external dependency
  • No need to extend main class with SpringBootServletInitializer
  • No need to add spring.datasource.jndi-name in application.properties
  • No need to create webapp/META-INF and context.xml
  • No need to generate WAR 

Rather just add one more java class which takes care of datasource and JNDI configuration 🙂 that’s it. Very easy with embedded tomcat.

TomcatConfigs.java

package com.java4s.app.configs;

import javax.naming.NamingException;
import javax.sql.DataSource;

import org.apache.catalina.Context;
import org.apache.catalina.startup.Tomcat;
import org.apache.tomcat.util.descriptor.web.ContextResource;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jndi.JndiObjectFactoryBean;

@Configuration
public class TomcatConfigs {
	
	 @Bean
	 public TomcatEmbeddedServletContainerFactory tomcatFactory() {
	        
		 return new TomcatEmbeddedServletContainerFactory() {
	          
	           @Override
	           protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(Tomcat tomcat) 
	           {
	                tomcat.enableNaming();
	                return super.getTomcatEmbeddedServletContainer(tomcat);
	            }
	        	
	            @Override
	            protected void postProcessContext(Context context) 
	            {
	                ContextResource resource = new ContextResource();

	                resource.setType(DataSource.class.getName());
	                resource.setName("j4s");
	                resource.setProperty("factory", "org.apache.tomcat.jdbc.pool.DataSourceFactory");
	                resource.setProperty("driverClassName", "com.mysql.jdbc.Driver");
	                resource.setProperty("url", "jdbc:mysql://localhost/test");
	                resource.setProperty("username", "java4s");
	                resource.setProperty("password", "java4s");
	                
	                context.getNamingResources().addResource(resource);
	            }
	        };
	    }
	 
	    @Bean
	    public DataSource jndiDataSource() throws IllegalArgumentException, NamingException 
	    {
	        JndiObjectFactoryBean bean = new JndiObjectFactoryBean();    
	        bean.setJndiName("java:/comp/env/j4s");
	        bean.setProxyInterface(DataSource.class);
	        bean.setLookupOnStartup(false);
	        bean.afterPropertiesSet();
	        
	        return (DataSource) bean.getObject();
	    }
}

Output

Hope you enjoy the article and consider sharing this with your friends 🙂 BTW download the code and play with it

相關文章
相關標籤/搜索