一、什么是JNDI?

JNDI(Java Naming and Directory Interface,Java命名和目录接口):在程序中使用JNDI获取数据源。说白了就是把数据源取个名字,再根据名字来找数据源。

在JDBC时代,需要把数据库信息,写在代码中去连接。

使用JNDI就是把数据库的连接信息放到j2ee的容器中取一个名字。例如放到tomcat的conf/context.xml中

 

二、本地springboot项目JNDI怎么配置?

1、配置文件增加jndi的name

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

2、增加配置类,定义内置tomcat工厂bean。先打开jndi数据源,再添加Context资源到tomcat上下文中。

@Configuration
public class TomcatConfigs {
	
	@Bean
    public TomcatEmbeddedServletContainerFactory tomcatFactory() {
        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.setName("jdbc/mysql/test");
                resource.setType(DataSource.class.getName());
                resource.setProperty("driverClassName", "com.mysql.jdbc.Driver");
                resource.setProperty("url", "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8");
                resource.setProperty("username", "root");
                resource.setProperty("password","root");
                //数据库连接池
                resource.setProperty("maxTotal","100");
                resource.setProperty("maxIdle","80");
                resource.setProperty("minIdle","10");
                resource.setProperty("maxWaitMillis","30000");
                resource.setProperty("testOnCreate","false");
                resource.setProperty("testOnBorrow","true");
                resource.setProperty("testOnReturn","false");
                resource.setProperty("testWhileIdle","false");
                resource.setProperty("numTestsPerEvictionRun","3");//设定在进行后台对象清理时,每次检查几个链接
                resource.setProperty("minEvictableIdleTimeMillis","1800000");//空闲逐出连接池的时间 毫秒
                context.getNamingResources().addResource(resource);
            }
        };
    }	
	
}

3、之后项目启动时,满足springboot-autoconfig的JndiDataSourceAutoConfiguration。就开始使用jndi连接数据库,创建连接池。

4、完毕

JndiDataSourceAutoConfiguration源码如下:

spring boot配置数据源 springboot配置jndi数据源_tomcat

注意:JNID使用的是org.apache.tomcat.dbcp.dbcp2.BasicDataSource数据源、连接池是:GenericObjectPool<PoolableConnection>

附加:手动获取JNDI数据库连接方式

// 获取数据库连接
  public Connection getConnection() {
   try {
    //初始化上下文
    Context cxt=new InitialContext();
    //获取与逻辑名相关联的数据源对象
    DataSource ds=(DataSource)cxt.lookup("java:comp/env/jdbc/test");
    conn=ds.getConnection();
   } catch (NamingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   } catch (SQLException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
   return conn;
  }

JNDI包括5个包:

  • javax.naming:主要用于命名操作,它包含了命名服务的类和接口,该包定义了Context接口和InitialContext类;
  • javax.naming.directory:主要用于目录操作,它定义了DirContext接口和InitialDir- Context类;
  • javax.naming.event:在命名目录服务器中请求事件通知;
  • javax.naming.ldap:提供LDAP支持;
  • javax.naming.spi:允许动态插入不同实现,为不同命名目录服务供应商的开发人员提供开发和实现的途径,以便应用程序通过JNDI可以访问相关服务。

常用的JNDI操作如下:

  • void bind(String sName,Object object),绑定:把名称同对象关联的过程。
  • void rebind(String sName,Object object),重新绑定:用来把对象同一个已经存在的名称重新绑定。一般使用rebind()而不使用bind(),因为当有重名的时候rebind()不会出现异常,而bind()会报异常。
  • void unbind(String sName),释放:用来把对象从目录中释放出来。
  • void lookup(String sName,Object object),查找:返回目录总的一个对象。
  • void rename(String sOldName,String sNewName),重命名:用来修改对象名称绑定的名称。
  • NamingEnumeration listBindings(String sName),清单:返回绑定在特定上下文中指定属性名对象的清单列表,它返回名字、类和对象本身,它用于那些需要对对象进行实际操作的应用。

三、生产环境tomcat JNDI怎么配置?

1、在lib/server.xml文件中<Server>节点下的<GlobalNamingResources>节点下添加下面的资源定义

<Resource name="jdbc/mysql/test" 
      auth="Container"
      type="javax.sql.DataSource"
      maxTotal="1000" 
      maxWaitMillis="10000"
      driverClassName="com.mysql.jdbc.Driver" 
      username="root"
      password="root" 
      url="jdbc:mysql://192.168.1.10:3306/jsw?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=fals
e"
    />

参数:

name=指定Resource的JNDI名称
  auth=指定管理Resource的Manager(Container由容器创建和管理,Application由Web应用创建和管理)
  type=指定Resource的java类
  maxActive=指定连接池中处于活动状态的数据库连接的最大数量
  maxIdle=指定连接池中处于空闲状态的数据库的最大数量
  maxWait=指定连接池中连接处于空闲的最长时间,超过这个时间会提示异常

2、在lib/context.xml文件中<Context>节点中添加下面的资源引用<ResourceLink>。 

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

3、将数据库的驱动jar包,放到Tomcat安装目录下的lib文件夹中。

提示:jndi数据源配置的密码应该是要加密存放在<Resources>中,只是我没有细致了解,请另行百度