annotations - Spring LDAP PoolingContextSource 通过注解

标签 annotations spring-ldap

我试图将 Spring LDAP PoolingContextSource XML 配置转换为使用注释。我可以通过提及 here 来让 LdapContextSource 工作,但我无法使 PoolingContextSource 正常工作。当我运行代码时,我得到了 NullPointerException。下面列出了 XML、注释和异常片段。

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 - 基于 here 的答案

@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())

@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;
}

关于annotations - Spring LDAP PoolingContextSource 通过注解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30309451/

相关文章:

python - 如何使用 python 在条形图上添加总计数?

java - Spring 3.1 LDAP 认证流程 : "Bad Credentials" msg When Credentials Are Good

spring - 使用多个后缀值/域验证 ldap 用户

java - 有没有办法在特定类的子类中强制使用特定的 Java 注释

java - 区分 InvalidAttributeValueException 的原因

java - 为什么 SpringLDAP/普通 Java AD 查询中的 accountExpires 和 userAccountControl 过滤器不能按预期工作?

java - 为什么在执行 ldapTemplate.authenticate() 时 baseDN 不正确?

Java 8 中包含 lambda 表达式的注解

java - @ElementCollection Java持久化(Hibernate)导致加载重复实例

java - 如何对带注释的方法的每个方法调用执行某些操作?