问题描述
我试图将 Spring LDAP PoolingContextSource XML 配置转换为使用注释.我可以通过遵循一个提及 此处,但我无法使 PoolingContextSource 工作.当我运行代码时,我得到了 NullPointerException.XML、注释和异常片段如下所列.
I was trying to convert the Spring LDAP PoolingContextSource XML configuration to use annotation. I am able to get the LdapContextSource working by following the one mention here, but I can't get the PoolingContextSource working. When I ran the code, I got NullPointerException. XML, annotation and exception snippet are listed below.
XML 配置片段,
<ldap:context-source
id="ldapContextSource"
username="${ldap.username}"
password="${ldap.password}"
url="${ldap.url}"
base="${ldap.base}">
<ldap:pooling
test-on-borrow="true"
test-while-idle="true"/>
</ldap:context-source>
<ldap:ldap-template id="ldapTemplate" context-source-ref="ldapContextSource"/>
注解配置片段,
@Bean
public ContextSource ldapContextSource() {
LdapContextSource contextSource = new LdapContextSource();
contextSource.setUrl(ldapUrl);
contextSource.setBase(ldapBase);
contextSource.setUserDn(ldapUsername);
contextSource.setPassword(ldapPassword);
PoolingContextSource poolingContextSource = new PoolingContextSource();
poolingContextSource.setDirContextValidator(new DefaultDirContextValidator());
poolingContextSource.setContextSource(contextSource);
poolingContextSource.setTestOnBorrow(true);
poolingContextSource.setTestWhileIdle(true);
TransactionAwareContextSourceProxy proxy = new TransactionAwareContextSourceProxy(poolingContextSource);
return proxy;
}
@Bean
public LdapTemplate ldapTemplate() {
return new LdapTemplate(ldapContextSource());
}
异常,
Exception in thread "main" org.springframework.dao.DataAccessResourceFailureException: Failed to borrow DirContext from pool.; nested exception is java.lang.NullPointerException
at org.springframework.ldap.pool.factory.PoolingContextSource.getContext(PoolingContextSource.java:446)
at org.springframework.ldap.pool.factory.PoolingContextSource.getReadWriteContext(PoolingContextSource.java:429)
at org.springframework.ldap.transaction.compensating.manager.TransactionAwareContextSourceProxy.getReadWriteContext(TransactionAwareContextSourceProxy.java:88)
at org.springframework.ldap.transaction.compensating.manager.TransactionAwareContextSourceProxy.getReadOnlyContext(TransactionAwareContextSourceProxy.java:61)
at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:357)
at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:309)
at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:642)
at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:578)
at org.springframework.ldap.core.LdapTemplate.find(LdapTemplate.java:1836)
at org.springframework.ldap.core.LdapTemplate.find(LdapTemplate.java:1857)
at org.springframework.ldap.core.LdapTemplate.findOne(LdapTemplate.java:1865)
at org.example.playground.ldap.spring.PersonDaoImpl.getByAccountId(PersonDaoImpl.java:23)
at org.example.playground.ldap.spring.Main.main(Main.java:19)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: java.lang.NullPointerException
at org.springframework.ldap.core.support.AbstractContextSource.getReadWriteContext(AbstractContextSource.java:175)
at org.springframework.ldap.pool.factory.DirContextPoolableObjectFactory.makeObject(DirContextPoolableObjectFactory.java:149)
at org.apache.commons.pool.impl.GenericKeyedObjectPool.borrowObject(GenericKeyedObjectPool.java:1220)
at org.springframework.ldap.pool.factory.PoolingContextSource.getContext(PoolingContextSource.java:443)
... 17 more
推荐答案
解决方案 1 - 基于 这里
@Bean
public ContextSource ldapContextSource() {
LdapContextSource contextSource = new LdapContextSource();
contextSource.setUrl(ldapUrl);
contextSource.setBase(ldapBase);
contextSource.setUserDn(ldapUsername);
contextSource.setPassword(ldapPassword);
contextSource.afterPropertiesSet(); // *** need this ***
PoolingContextSource poolingContextSource = new PoolingContextSource();
poolingContextSource.setDirContextValidator(new DefaultDirContextValidator());
poolingContextSource.setContextSource(contextSource);
poolingContextSource.setTestOnBorrow(true);
poolingContextSource.setTestWhileIdle(true);
TransactionAwareContextSourceProxy proxy = new TransactionAwareContextSourceProxy(poolingContextSource);
return proxy;
}
方案 2 - 将 LdapContextSource 和 PoolingContextSource 的创建分开,spring 容器会负责 bean 的生命周期(即 afterPropertiesSet())
Solution 2 - separate the creation of LdapContextSource and PoolingContextSource, the spring container will take care the lifecycle of the beans (i.e. afterPropertiesSet())
@Bean
public LdapContextSource ldapContextSource() {
LdapContextSource contextSource = new LdapContextSource();
contextSource.setUrl(ldapUrl);
contextSource.setBase(ldapBase);
contextSource.setUserDn(ldapUsername);
contextSource.setPassword(ldapPassword);
return contextSource;
}
@Bean
public ContextSource poolingLdapContextSource() {
PoolingContextSource poolingContextSource = new PoolingContextSource();
poolingContextSource.setDirContextValidator(new DefaultDirContextValidator());
poolingContextSource.setContextSource(ldapContextSource());
poolingContextSource.setTestOnBorrow(true);
poolingContextSource.setTestWhileIdle(true);
TransactionAwareContextSourceProxy proxy = new TransactionAwareContextSourceProxy(poolingContextSource);
return proxy;
}
这篇关于Spring LDAP PoolingContextSource 通过注解的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!