Quick look of JNDI (Java Naming and Directory Interface)

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
java:/comp/env/jdbc/db1
java:/comp/env/jdbc/db1

Enter fullscreen mode Exit fullscreen mode

To get that data source

<span>javax</span><span>.</span><span>naming</span><span>.</span><span>Context</span> <span>initialContext</span> <span>=</span> <span>new</span> <span>javax</span><span>.</span><span>naming</span><span>.</span><span>InitialContext</span><span>();</span>
<span>javax</span><span>.</span><span>naming</span><span>.</span><span>Context</span> <span>subContext</span> <span>=</span> <span>(</span><span>javax</span><span>.</span><span>naming</span><span>.</span><span>Context</span><span>)</span> <span>initialContext</span><span>.</span><span>lookup</span><span>(</span><span>"java:comp/env"</span><span>);</span>
<span>DataSource</span> <span>dataSource</span> <span>=</span> <span>(</span><span>DataSource</span><span>)</span> <span>subContext</span><span>.</span><span>lookup</span><span>(</span><span>"jdbc/db1"</span><span>);</span>
<span>javax</span><span>.</span><span>naming</span><span>.</span><span>Context</span> <span>initialContext</span> <span>=</span> <span>new</span> <span>javax</span><span>.</span><span>naming</span><span>.</span><span>InitialContext</span><span>();</span>
<span>javax</span><span>.</span><span>naming</span><span>.</span><span>Context</span> <span>subContext</span> <span>=</span> <span>(</span><span>javax</span><span>.</span><span>naming</span><span>.</span><span>Context</span><span>)</span> <span>initialContext</span><span>.</span><span>lookup</span><span>(</span><span>"java:comp/env"</span><span>);</span>
<span>DataSource</span> <span>dataSource</span> <span>=</span> <span>(</span><span>DataSource</span><span>)</span> <span>subContext</span><span>.</span><span>lookup</span><span>(</span><span>"jdbc/db1"</span><span>);</span>
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");

Enter fullscreen mode Exit fullscreen mode

Or you may get the instance directly by providing the full path

<span>javax</span><span>.</span><span>naming</span><span>.</span><span>Context</span> <span>initialContext</span> <span>=</span> <span>new</span> <span>javax</span><span>.</span><span>naming</span><span>.</span><span>InitialContext</span><span>();</span>
<span>DataSource</span> <span>dataSource</span> <span>=</span> <span>(</span><span>DataSource</span><span>)</span> <span>initialContext</span><span>.</span><span>lookup</span><span>(</span><span>"java:comp/env/jdbc/db1"</span><span>);</span>
<span>javax</span><span>.</span><span>naming</span><span>.</span><span>Context</span> <span>initialContext</span> <span>=</span> <span>new</span> <span>javax</span><span>.</span><span>naming</span><span>.</span><span>InitialContext</span><span>();</span>
<span>DataSource</span> <span>dataSource</span> <span>=</span> <span>(</span><span>DataSource</span><span>)</span> <span>initialContext</span><span>.</span><span>lookup</span><span>(</span><span>"java:comp/env/jdbc/db1"</span><span>);</span>
javax.naming.Context initialContext = new javax.naming.InitialContext(); DataSource dataSource = (DataSource) initialContext.lookup("java:comp/env/jdbc/db1");

Enter fullscreen mode Exit fullscreen mode

Spring boot integration

Just add a line into application.properties

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

Enter fullscreen mode Exit fullscreen mode

The related bean is created by org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration

<span>@Configuration</span><span>(</span><span>proxyBeanMethods</span> <span>=</span> <span>false</span><span>)</span>
<span>@AutoConfigureBefore</span><span>({</span> <span>XADataSourceAutoConfiguration</span><span>.</span><span>class</span><span>,</span> <span>DataSourceAutoConfiguration</span><span>.</span><span>class</span> <span>})</span>
<span>@ConditionalOnClass</span><span>({</span> <span>DataSource</span><span>.</span><span>class</span><span>,</span> <span>EmbeddedDatabaseType</span><span>.</span><span>class</span> <span>})</span>
<span>@ConditionalOnProperty</span><span>(</span><span>prefix</span> <span>=</span> <span>"spring.datasource"</span><span>,</span> <span>name</span> <span>=</span> <span>"jndi-name"</span><span>)</span>
<span>@EnableConfigurationProperties</span><span>(</span><span>DataSourceProperties</span><span>.</span><span>class</span><span>)</span>
<span>public</span> <span>class</span> <span>JndiDataSourceAutoConfiguration</span> <span>{</span>
<span>@Bean</span><span>(</span><span>destroyMethod</span> <span>=</span> <span>""</span><span>)</span>
<span>@ConditionalOnMissingBean</span>
<span>public</span> <span>DataSource</span> <span>dataSource</span><span>(</span><span>DataSourceProperties</span> <span>properties</span><span>,</span> <span>ApplicationContext</span> <span>context</span><span>)</span> <span>{</span>
<span>JndiDataSourceLookup</span> <span>dataSourceLookup</span> <span>=</span> <span>new</span> <span>JndiDataSourceLookup</span><span>();</span>
<span>DataSource</span> <span>dataSource</span> <span>=</span> <span>dataSourceLookup</span><span>.</span><span>getDataSource</span><span>(</span><span>properties</span><span>.</span><span>getJndiName</span><span>());</span>
<span>excludeMBeanIfNecessary</span><span>(</span><span>dataSource</span><span>,</span> <span>"dataSource"</span><span>,</span> <span>context</span><span>);</span>
<span>return</span> <span>dataSource</span><span>;</span>
<span>}</span>
<span>private</span> <span>void</span> <span>excludeMBeanIfNecessary</span><span>(</span><span>Object</span> <span>candidate</span><span>,</span> <span>String</span> <span>beanName</span><span>,</span> <span>ApplicationContext</span> <span>context</span><span>)</span> <span>{</span>
<span>for</span> <span>(</span><span>MBeanExporter</span> <span>mbeanExporter</span> <span>:</span> <span>context</span><span>.</span><span>getBeansOfType</span><span>(</span><span>MBeanExporter</span><span>.</span><span>class</span><span>).</span><span>values</span><span>())</span> <span>{</span>
<span>if</span> <span>(</span><span>JmxUtils</span><span>.</span><span>isMBean</span><span>(</span><span>candidate</span><span>.</span><span>getClass</span><span>()))</span> <span>{</span>
<span>mbeanExporter</span><span>.</span><span>addExcludedBean</span><span>(</span><span>beanName</span><span>);</span>
<span>}</span>
<span>}</span>
<span>}</span>
<span>}</span>
<span>@Configuration</span><span>(</span><span>proxyBeanMethods</span> <span>=</span> <span>false</span><span>)</span>
<span>@AutoConfigureBefore</span><span>({</span> <span>XADataSourceAutoConfiguration</span><span>.</span><span>class</span><span>,</span> <span>DataSourceAutoConfiguration</span><span>.</span><span>class</span> <span>})</span>
<span>@ConditionalOnClass</span><span>({</span> <span>DataSource</span><span>.</span><span>class</span><span>,</span> <span>EmbeddedDatabaseType</span><span>.</span><span>class</span> <span>})</span>
<span>@ConditionalOnProperty</span><span>(</span><span>prefix</span> <span>=</span> <span>"spring.datasource"</span><span>,</span> <span>name</span> <span>=</span> <span>"jndi-name"</span><span>)</span>
<span>@EnableConfigurationProperties</span><span>(</span><span>DataSourceProperties</span><span>.</span><span>class</span><span>)</span>
<span>public</span> <span>class</span> <span>JndiDataSourceAutoConfiguration</span> <span>{</span>

    <span>@Bean</span><span>(</span><span>destroyMethod</span> <span>=</span> <span>""</span><span>)</span>
    <span>@ConditionalOnMissingBean</span>
    <span>public</span> <span>DataSource</span> <span>dataSource</span><span>(</span><span>DataSourceProperties</span> <span>properties</span><span>,</span> <span>ApplicationContext</span> <span>context</span><span>)</span> <span>{</span>
        <span>JndiDataSourceLookup</span> <span>dataSourceLookup</span> <span>=</span> <span>new</span> <span>JndiDataSourceLookup</span><span>();</span>
        <span>DataSource</span> <span>dataSource</span> <span>=</span> <span>dataSourceLookup</span><span>.</span><span>getDataSource</span><span>(</span><span>properties</span><span>.</span><span>getJndiName</span><span>());</span>
        <span>excludeMBeanIfNecessary</span><span>(</span><span>dataSource</span><span>,</span> <span>"dataSource"</span><span>,</span> <span>context</span><span>);</span>
        <span>return</span> <span>dataSource</span><span>;</span>
    <span>}</span>

    <span>private</span> <span>void</span> <span>excludeMBeanIfNecessary</span><span>(</span><span>Object</span> <span>candidate</span><span>,</span> <span>String</span> <span>beanName</span><span>,</span> <span>ApplicationContext</span> <span>context</span><span>)</span> <span>{</span>
        <span>for</span> <span>(</span><span>MBeanExporter</span> <span>mbeanExporter</span> <span>:</span> <span>context</span><span>.</span><span>getBeansOfType</span><span>(</span><span>MBeanExporter</span><span>.</span><span>class</span><span>).</span><span>values</span><span>())</span> <span>{</span>
            <span>if</span> <span>(</span><span>JmxUtils</span><span>.</span><span>isMBean</span><span>(</span><span>candidate</span><span>.</span><span>getClass</span><span>()))</span> <span>{</span>
                <span>mbeanExporter</span><span>.</span><span>addExcludedBean</span><span>(</span><span>beanName</span><span>);</span>
            <span>}</span>
        <span>}</span>
    <span>}</span>

<span>}</span>
@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); } } } }

Enter fullscreen mode Exit fullscreen mode

原文链接:Quick look of JNDI (Java Naming and Directory Interface)

© 版权声明
THE END
喜欢就支持一下吧
点赞13 分享
The sacrifices you make today will pay dividends in the future.
今天的牺牲和努力未来都会有回报
评论 抢沙发

请登录后发表评论

    暂无评论内容