Simple to say, programmer can use the same JNDI interface to query the following
- lookup resources provided by application server, such as data source
- search LDAP entries
- lookup DNS records
Brief introduction is here.
The code
Resources of the application server are placed under "java:comp/env" prefix. Assume that a data source is on
java:/comp/env/jdbc/db1
To get that data source
javax.naming.Context initialContext = new javax.naming.InitialContext();
javax.naming.Context subContext = (javax.naming.Context) initialContext.lookup("java:comp/env");
DataSource dataSource = (DataSource) subContext.lookup("jdbc/db1");
Or you may get the instance directly by providing the full path
javax.naming.Context initialContext = new javax.naming.InitialContext();
DataSource dataSource = (DataSource) initialContext.lookup("java:comp/env/jdbc/db1");
Spring boot integration
Just add a line into application.properties
spring.datasource.jndi-name=java:/comp/env/jdbc/db1
The related bean is created by org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration
@Configuration(proxyBeanMethods = false)
@AutoConfigureBefore({ XADataSourceAutoConfiguration.class, DataSourceAutoConfiguration.class })
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@ConditionalOnProperty(prefix = "spring.datasource", name = "jndi-name")
@EnableConfigurationProperties(DataSourceProperties.class)
public class JndiDataSourceAutoConfiguration {
@Bean(destroyMethod = "")
@ConditionalOnMissingBean
public DataSource dataSource(DataSourceProperties properties, ApplicationContext context) {
JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
DataSource dataSource = dataSourceLookup.getDataSource(properties.getJndiName());
excludeMBeanIfNecessary(dataSource, "dataSource", context);
return dataSource;
}
private void excludeMBeanIfNecessary(Object candidate, String beanName, ApplicationContext context) {
for (MBeanExporter mbeanExporter : context.getBeansOfType(MBeanExporter.class).values()) {
if (JmxUtils.isMBean(candidate.getClass())) {
mbeanExporter.addExcludedBean(beanName);
}
}
}
}