036. [Switch] the JNDI

Demand:  How to use jndi in spring boot in

(1) JNDI Why born?

(2) What is JNDI?

(3) how to play JNDI in Tomcat?

(4) Spring Boot in how to play JNDI

 

A, JNDI Why born?

1.1 JDBC dominated

If we want to connect to the database in the program if, in the absence of JNDI is to use JDBC (Java DataBase Connectivity, java database connectivity), is not already almost forgotten, together under review it, see the following connection database code

        Connection conn = null;
        try {
            Class.forName("com.mysql.jdbc.Driver", true, Thread.currentThread().getContextClassLoader());
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb?user=root&password=root");
            String sql = "select *from test";
            PreparedStatement ps = conn.prepareStatement(sql);
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                System.out.println("id:" + rs.getInt("id") + ",name:" + rs.getString("name") + "");
            }
            conn.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                }
            }
        }

 

       This is in no connection with JNDI.

 

1.2  Problems?

       What exists in this way the above problem is it?

(1) database server name mydb, user name and password may need to change, triggered JDBC URL needs to be modified;

(2) The database may switch to other products, such as switching the Oracle or DB2, initiator JDBC Driver class name and the package needs to be modified;

(3) With the increase of the actual use of the terminal, the connection pool configuration parameters may require adjustments to the original;

Note: actually using the Spring framework and other fast hardware after the fact above these problems is no longer a problem.

 

1.3  Solution

Programmers should not need to be concerned about "what specific database back-end? What JDBC driver is? What JDBC URL format? What user name and password to access the database is?" And so these issues, programs written for JDBC programmers should not drivers references, no server name, no user name or password - or even no database connection pool management. But these issues to the J2EE container configuration and management, the programmer only needs to configure and manage these can be referenced.

As a result, there will be a JNDI. It can be drawn from the above analysis, in fact, by the container to manage our information the database connection.

 

Second, what is JNDI?

We look description Baidu Encyclopedia (https://baike.baidu.com/item/JNDI/3792442):

JNDI (Java Naming and Directory Interface, Java Naming and Directory Interface) is a standard provided by the SUN Java Naming System Interface, JNDI provides a uniform client API, JNDI service provider interface Interface (SPI) through different access implementation by the managers will JNDI API is mapped to specific naming and directory services system, so that Java applications can interact with and between these naming and directory services.

       After reading it, is not feeling very abstract it, we need to understand where so few points:

(1) JNDI one J2EE specification.

(2) JNDI has two main components: an application programming interface and service provider interface. Application Programming Interface provides a Java application to access a variety of naming and directory services, the service provider interface provides the ability to use any one vendor services.

(. 3) J2EE specifications required to provide all the J2EE containers JNDI implementation specification.

(4) The purpose is to understand the proposed JNDI lotus root, avoiding the tight coupling between the program and the database, make the application more easy to configure, easy to deploy.

Voiceover: JNDI appearance, so the database connection code to container management, such as Tomcat, JBOSS and other containers, so developers do not have to care what database configuration is, what database driver to use database connection.

 

https://mp.weixin.qq.com/s?__biz=MzA4ODIyMzEwMg==&mid=2447533543&idx=1&sn=7a3aeab6a2fb29c026a420af2a70460d&chksm=843bb9f6b34c30e0ed2da36b25af7a96b08c696b22ed7767e1271ed71707cc129c007253d4a7&scene=21#wechat_redirect

 

Third, how to use JNDI in Tomcat?

 Tomcat JNDI configuration and with a local configuration global configuration. There are roughly three configurations:

(1) global configuration: context.xml based configuration.

(2) local configuration: server.xml based configuration.

(3) partial configuration: Configuration based on the META-INF.

 

The first: Global: based context.xml configuration

1) added to tomcat's conf / context.xml configuration file

<?xml version="1.0" encoding="UTF-8"?>
<Context >  
 <Resource name="jdbc/mydb" 
     auth="Container" 
     type="javax.sql.DataSource" 
     driverClassName="com.mysql.jdbc.Driver" 
     url="jdbc:mysql://localhost:3306/mydb" 
     username="root" password="root" 
     maxActive="20" maxIdle="10" 
     maxWait="10000"/>
</Context>

 

Special Note: If you are using the eclipse development testing, it may encounter the following exception information:

Cannot create JDBC driver of class '' for connect URL 'null'

      This is because context.xml in the development of tools under /context.xml servers, so it is necessary configuration information servers / Tomcat / context.xml.

 

2) adding resources in web.xml project references (non-mandatory):

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

Wherein the res-ref-name and value to context.xml the same name value.

Special Note: This configuration is optional, do not configure this, then, it is to run normally.

 

3) In the call load jndi jsp way:

    Connection conn =null;
      try{
           //初始化查找命名空间
           Context ctx = new InitialContext(); 
           //InitialContext ctx = new InitialContext();亦可 
           //找到DataSource,对名称进行定位java:comp/env是必须加的,后面跟你的DataSource名
           DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/mydb");
           //取出连接
            conn = ds.getConnection();
           String sql = "select *from test";
           PreparedStatement ps = conn.prepareStatement(sql);
           ResultSet rs = ps.executeQuery();
            while(rs.next()){
                 System.out.println("id:"+rs.getInt("id")+",name:"+rs.getString("name")+"");
            }
           out.println(conn);
           out.println(conn.isClosed());
           out.println("</br>");
            System.out.println("connection pool connected !!");   
      } catch (NamingException e) {
       System.out.println(e.getMessage());
      } catch (SQLException e) {
       e.printStackTrace();
      }finally{
           //注意不是关闭,是放回连接池.
           conn.close();
      }

特别注意:不可以直接用main方法测试,必须通过启动容器从jsp中调用

 

第二种:局部配置:基于server.xml的配置(不推荐使用)

在tomcat的server.xml的<host>标签内,添加:

   <Context docBase="demo-jndi" path="/demo-jndi">
           <Resource name="jdbc/mydb" 
             auth="Container" 
             type="javax.sql.DataSource" 
             driverClassName="com.mysql.jdbc.Driver" 
             url="jdbc:mysql://localhost:3306/mydb" 
             username="root" password="root" 
             maxActive="20" maxIdle="10" 
            maxWait="10000"/>
   </Context>

 

其他配置同第一种方式。

 

第三种:局部配置:基于META-INFO的配置

在项目的META-INF 下面新建context.xml加入:

<?xml version="1.0" encoding="UTF-8"?>
<Context >  
 <Resource name="jdbc/mydb" 
     auth="Container" 
     type="javax.sql.DataSource" 
     driverClassName="com.mysql.jdbc.Driver" 
     url="jdbc:mysql://localhost:3306/mydb" 
     username="root" password="root" 
     maxActive="20" maxIdle="10" 
     maxWait="10000"/>
</Context>

其他配置同第一种方式。

 

总结:

如果要配置局部的话,推荐使用第三种方式,这样不依赖tomcat了。但是还是推荐使用第一种方式好,虽然依赖Tomcat,但是是全局的,而且可以配置多个。对于以后切换使用方便。另外在项目的web.xml中添加的资源引用可有可无。

 

https://mp.weixin.qq.com/s?__biz=MzA4ODIyMzEwMg==&mid=2447533547&idx=1&sn=dbc4385eca1ba546fe3bf19f674e4ec3&chksm=843bb9fab34c30ecc62643616e859539bfbcd4d2eb9ba99ae5eee04096bd13d8bbfabcd4bce6&scene=21#wechat_redirect

 

 

四、在SpringBoot中如何使用JNDI?

SpringBoot使用内置的Tomcat

 

1、新增application-dev.properties文件:

# dev环境配置
DataSource.jndiName=jdbc/timcore/DefaultDS
DataSource.auth=Container
DataSource.driverClassName=org.postgresql.Driver
DataSource.url=jdbc:postgresql://30.31.0.14:7523/timc
DataSource.username=timcopr
DataSource.pwd=123456
DataSource.maxActive=100
DataSource.maxIdle=30
DataSource.maxWait=10000

 

2、创建一个PropConfig类,接收配置

@Getter
@Setter
@Component
@ConfigurationProperties(prefix = "DataSource")
public class DataSourcePropConfig {
    private String jndiName;
    private String auth;
    private String driverClassName;
    private String url;
    private String username;
    private String pwd;
    private String maxActive;
    private String maxIdle;
    private String maxWait;
}

 

3、JavaConfig 方式修改配置,加入数据源

@Configuration
public class MyWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter {
    
    @Resource
    private DataSourcePropConfig dataSourcePropConfig;
    
    // dev 环境数据源。
    @ConditionalOnProperty(name = "spring.profiles.active", havingValue = "dev") 
    @Bean
    public TomcatEmbeddedServletContainerFactory servletContainerFactory() {
        return new TomcatEmbeddedServletContainerFactory() {
            @Override
            protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(Tomcat tomcat) {
                tomcat.enableNaming(); // 打开JNDI数据源
                return super.getTomcatEmbeddedServletContainer(tomcat);
            }
            
            @Override
            protected void postProcessContext(Context context) {
                ContextResource resource = new ContextResource();
                resource.setType(DataSource.class.getName());
                resource.setName(dataSourcePropConfig.getJndiName());
                resource.setAuth(dataSourcePropConfig.getAuth());
                resource.setProperty("driverClassName", dataSourcePropConfig.getDriverClassName());
                resource.setProperty("url", dataSourcePropConfig.getUrl());
                resource.setProperty("username", dataSourcePropConfig.getUsername());
                resource.setProperty("password", dataSourcePropConfig.getPwd());
                // 连接池配置,和测试、生产配置一致。
                resource.setProperty("maxActive", dataSourcePropConfig.getMaxActive()); // 最大连接数
                resource.setProperty("maxIdle", dataSourcePropConfig.getMaxIdle()); // 空闲连接数
                resource.setProperty("maxWait", dataSourcePropConfig.getMaxWait()); // 最大等待时间
                context.getNamingResources().addResource(resource);
            }
        };
    }
}

 

4、SpringBoot使用JNDI数据源

application.properties文件中配置

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

 

 

https://juejin.im/post/5ca6214f51882543e85f0fd6

 

Guess you like

Origin www.cnblogs.com/badboyh2o/p/11258186.html