轉載自 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
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 username, passwordand url.sql
<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>
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); } }
spring.datasource.jndi-name=java:comp/env/jdbc/j4s
<?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
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; } }
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; } }
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
You can download and play with the code 🙂webapp
Lets compare the steps we have followed for the configuration done above for external tomcat server, for Embedded tomcat…maven
Rather just add one more java class which takes care of datasource and JNDI configuration 🙂 that’s it. Very easy with embedded tomcat.
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(); } }
Hope you enjoy the article and consider sharing this with your friends 🙂 BTW download the code and play with it