连接池支持
LDAP 连接池有助于减轻每次 LDAP 交互创建新连接的开销。虽然 Java LDAP 连接池支持 已经存在,但其配置选项和功能有限,例如连接验证和连接池维护。Spring LDAP 支持基于每个 ContextSource
进行详细的连接池配置。
通过在应用上下文配置中的 <ldap:context-source />
元素中提供一个 <ldap:pooling />
子元素来提供连接池支持。只读和读写 DirContext
对象会分开进行连接池管理(如果指定了 anonymous-read-only
)。Jakarta Commons-Pool 被用来提供底层连接池实现。
DirContext
验证
相较于 JDK 提供的 LDAP 连接池功能,使用自定义连接池库的主要动机是能够对连接池中的连接进行验证。验证允许检查连接池中的 DirContext
连接,以确保它们在从连接池中取出、放回连接池或在连接池中空闲时仍保持正确连接和配置。
如果配置了连接验证,将使用 DefaultDirContextValidator
来验证连接池中的连接。DefaultDirContextValidator
执行一个 DirContext.search(String, String, SearchControls)
操作,使用空名称、过滤器 "objectclass=*"
,并将 SearchControls
设置为只返回一个结果,仅包含 objectclass
属性,超时时间为 500ms。如果返回的 NamingEnumeration
有结果,则 DirContext
通过验证。如果没有返回结果或抛出异常,则 DirContext
验证失败。默认设置适用于大多数 LDAP 服务器,无需配置更改,并提供了验证 DirContext
的最快方法。如果需要自定义,可以使用 连接池配置 中描述的验证配置属性进行设置。
如果连接抛出被视为非瞬时(non-transient)的异常,它们会自动失效。例如,如果一个 DirContext 实例抛出 javax.naming.CommunicationException ,它会被解释为非瞬时错误,并且该实例会自动失效,而无需额外的 testOnReturn 操作开销。哪些异常被解释为非瞬时异常是通过 PoolingContextSource 的 nonTransientExceptions 属性配置的。 |
连接池配置
<ldap:pooling />
元素上提供了以下属性,用于配置 DirContext 连接池
属性 | 默认值 | 描述 |
---|---|---|
|
|
同时可以从该连接池中分配的每种类型(只读或读写)的最大活动连接数。可以使用非正数表示无限制。 |
|
|
同时可以从该连接池中分配的所有类型(只读和读写总计)的最大活动连接总数。可以使用非正数表示无限制。 |
|
|
每种类型(只读或读写)在连接池中可以保持空闲的最大活动连接数,超过此数量时,额外的连接将被释放。可以使用非正数表示无限制。 |
|
|
每种类型(只读或读写)在连接池中可以保持空闲的最小活动连接数,低于此数量时,将创建额外的连接。可以使用零(默认值)表示不创建。 |
|
|
当没有可用连接时,连接池等待连接返回的最大毫秒数,超过此时间将抛出异常。可以使用非正数表示无限期等待。 |
|
|
指定当连接池耗尽时的行为。
|
|
|
从连接池中借用对象之前是否进行验证。如果对象验证失败,它将从连接池中移除,然后尝试借用另一个对象。 |
|
|
将对象返回到连接池之前是否进行验证。 |
|
|
对象是否由空闲对象驱逐器(如果存在)进行验证。如果对象验证失败,它将从连接池中移除。 |
|
|
空闲对象驱逐器线程每次运行之间的休眠毫秒数。非正数表示不运行空闲对象驱逐器线程。 |
|
|
空闲对象驱逐器线程每次运行时(如果存在)检查的对象数量。 |
|
|
对象在连接池中保持空闲的最短时间,超过此时间后,空闲对象驱逐器(如果存在)才有资格将其驱逐。 |
|
|
验证连接时使用的搜索基础。仅在指定 |
|
|
验证连接时使用的搜索过滤器。仅在指定 |
|
|
验证连接时使用的 |
|
|
以逗号分隔的 |
Pool2 配置
<ldap:pooling2 />
元素上提供了以下属性,用于配置 DirContext
连接池
属性 | 默认值 | 描述 |
---|---|---|
|
|
同时可以从该连接池中分配的所有类型(只读和读写总计)的最大活动连接总数。可以使用非正数表示无限制。 |
|
|
连接池按键(key)分配的对象实例数量限制(已借出或空闲)。达到限制时,子池耗尽。负值表示无限制。 |
|
|
每种类型(只读或读写)在连接池中可以保持空闲的最大活动连接数,超过此数量时,额外的连接将被释放。负值表示无限制。 |
|
|
每种类型(只读或读写)在连接池中可以保持空闲的最小活动连接数,低于此数量时,将创建额外的连接。可以使用零(默认值)表示不创建。 |
|
|
当没有可用连接时,连接池等待连接返回的最大毫秒数,超过此时间将抛出异常。可以使用非正数表示无限期等待。 |
|
|
是否等待直到有新对象可用。如果 max-wait 为正数,并且在 |
|
|
在借用对象之前是否进行验证。如果对象验证失败,则借用失败。 |
|
|
从连接池中借用对象之前是否进行验证的指示器。如果对象验证失败,它将从连接池中移除,然后尝试借用另一个对象。 |
|
|
将对象返回到连接池之前是否进行验证的指示器。 |
|
|
对象是否由空闲对象驱逐器(如果存在)进行验证的指示器。如果对象验证失败,它将从连接池中移除。 |
|
|
空闲对象驱逐器线程每次运行之间的休眠毫秒数。非正数表示不运行空闲对象驱逐器线程。 |
|
|
空闲对象驱逐器线程每次运行时(如果存在)检查的对象数量。 |
|
|
对象在连接池中保持空闲的最短时间,超过此时间后,空闲对象驱逐器(如果存在)才有资格将其驱逐。 |
|
|
对象在连接池中保持空闲的最短时间,超过此时间后,空闲对象驱逐器才有资格将其驱逐,但附加条件是每个键(key)至少保留最小数量的对象实例。如果 |
|
|
此连接池使用的驱逐策略实现。连接池尝试使用线程上下文类加载器加载该类。如果失败,连接池将尝试使用加载此类的类加载器加载该类。 |
|
|
连接池公平地服务等待借用连接的线程。 |
|
|
为连接池启用了平台 MBean 服务器的 JMX。 |
|
|
用作 JMX 启用连接池名称一部分的 JMX 名称基础。 |
|
|
用作 JMX 启用连接池名称一部分的 JMX 名称前缀。 |
|
|
指示连接池对空闲对象是否具有 LIFO(后进先出)行为或作为 FIFO(先进先出)队列。LIFO 总是返回连接池中最近使用的对象,而 FIFO 总是返回空闲对象池中最旧的对象。 |
|
|
用于验证搜索的基础 DN。 |
|
|
用于验证查询的过滤器。 |
|
|
验证连接时使用的 |
|
|
以逗号分隔的 |
配置
配置连接池需要在 <ldap:context-source>
元素中嵌套添加一个 <ldap:pooling>
元素,如下所示
<beans>
...
<ldap:context-source
password="secret" url="ldap://localhost:389" username="cn=Manager">
<ldap:pooling />
</ldap:context-source>
...
</beans>
在实际情况中,你可能会配置连接池选项并启用连接验证。上面的示例展示了基本思路。
已知问题
本节描述了人们在使用 Spring LDAP 时有时会遇到的问题。目前,它涵盖了以下问题
自定义认证
PoolingContextSource
假定从 ContextSource.getReadOnlyContext()
获取的所有 DirContext
对象都具有相同的环境,同样地,从 ContextSource.getReadWriteContext()
获取的所有 DirContext
对象也具有相同的环境。这意味着将配置了 AuthenticationSource
的 LdapContextSource
包装到 PoolingContextSource
中时,其行为不会按预期进行。连接池将使用第一个用户的凭据填充,并且除非需要新的连接,否则后续的上下文请求将不会为请求线程指定的 AuthenticationSource
用户填充。