池化支持
连接LDAP池有助于减轻每次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。
如果需要自定义,可以通过使用验证配置属性进行设置,详情请参阅池配置。
连接如果抛出被认为是“非瞬时”的异常将被自动作废。例如,如果一个DirContext实例抛出一个javax.naming.CommunicationException,它将被解释为非瞬时错误,实例将自动作废,而无需额外的testOnReturn操作。被解释为非瞬时的异常可通过nonTransientExceptions属性配置PoolingContextSource。 |
池配置
以下在 <ldap:pooling /> 元素上可用于配置 DirContext 池的属性:
| 属性 | 默认 | 描述 |
|---|---|---|
|
|
每种类型(只读或读写)的最大活动连接数,该池在同一时间可为此分配的最大连接数。你可以使用非正数表示无限制。 |
|
|
该池在同一时间可分配的最大活动连接数(适用于所有类型)。您可以使用非正数表示无限制。 |
|
|
每种类型(只读或读写)的最大空闲连接数,这些连接可以在池中保持空闲而不释放额外连接。你可以使用非正数表示不限制。 |
|
|
每种类型(只读或读写)的最小空闲连接数,该数可在连接池中保持而不创建额外连接。你可以使用零(默认值)来创建不创建任何连接。 |
|
|
当池中没有连接可用时,最大等待毫秒数(在连接被返回之前)以抛出异常。你可以使用非正数来无限等待。 |
|
|
指定池耗尽时的行为。
|
|
|
是否在从池中借出对象之前进行验证。如果对象验证失败,将从池中移除,并尝试借取另一个对象。 |
|
|
是否在对象返回到池之前进行验证。 |
|
|
是否由空闲对象移除器(如果存在)进行验证。如果对象验证失败,将从池中移除它。 |
|
|
在空闲对象驱逐器线程的每次运行之间休眠的毫秒数。当为非正数时,不运行空闲对象驱逐器线程。 |
|
|
每个空闲对象回收器线程运行时检查的对象数量(如果存在该线程的话)。 |
|
|
在池中对象可以空闲的最短时间(以毫秒为单位)之前,该对象将有资格被空闲对象移除器(如果存在的话)移除。 |
|
|
用于在验证连接时使用的搜索基。仅当指定 |
|
|
用于连接验证的搜索过滤器。仅在指定了 |
|
|
用于验证连接的 |
|
|
逗号分隔的 |
Pool2 配置
以下属性可用于配置 <ldap:pooling2 /> 元素的 DirContext 池:
| 属性 | 默认 | 描述 |
|---|---|---|
|
|
该池在同一时间可分配的最大活动连接数(适用于所有类型)。您可以使用非正数表示无限制。 |
|
|
每个键分配的对象实例数量池的限制(已检查或空闲)。当达到限制时,子池耗尽。负值表示无限制。 |
|
|
每种类型(只读或读写)的最大空闲连接数,这些连接可以保留在池中而无需释放额外的连接。负值表示无限制。 |
|
|
每种类型(只读或读写)的最少活动连接数,这些连接可以处于空闲状态而无需创建额外连接。您可以使用零(默认值)来不创建任何。 |
|
|
连接池在没有可用连接时等待连接返回的最大毫秒数,超过该时间将抛出异常。您可以使用非正数来无限期等待。 |
|
|
是否要等到获取新对象。如果max-wait为正值,在 |
|
|
在借用对象之前是否进行验证。如果对象验证失败,则借用失败。 |
|
|
在从池中借用对象之前,是否验证对象的指示器。如果对象验证失败,则将其从池中丢弃,并尝试借用另一个对象。 |
|
|
对象在被返回到池之前是否经过验证的指示符。 |
|
|
对象是否由空闲对象驱逐程序(如果有的话)验证的指示符。如果某个对象无法通过验证,则会将其从池中删除。 |
|
|
在空闲对象驱逐器线程的每次运行之间休眠的毫秒数。当为非正数时,不运行空闲对象驱逐器线程。 |
|
|
每个空闲对象回收器线程运行时检查的对象数量(如果存在该线程的话)。 |
|
|
在池中对象可以空闲的最短时间(以毫秒为单位)之前,该对象将有资格被空闲对象移除器(如果存在的话)移除。 |
|
|
对象在池中空闲的最短时间,超过此时间后,该对象可能被空闲对象驱逐器从池中移除。但有一个额外条件:每个键至少保留最小数量的对象实例在池中。如果此设置为正数,则会被 |
|
|
此池所使用的驱逐策略实现。该池尝试使用线程上下文类加载器来加载此类。如果失败,则池会尝试使用加载此类型的类加载器来加载此类。 |
|
|
该池为等待借用连接的线程提供服务,公平地分配。 |
|
|
JMX 已针对该池启用平台 MBean 服务器。 |
|
|
用于分配给启用 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时有时会出现的问题。目前,它涵盖了以下问题:<br/>
自定义身份验证
该PoolingContextSource假设从ContextSource.getReadOnlyContext()检索的所有DirContext对象具有相同的环境,同样地,从ContextSource.getReadWriteContext()检索的所有DirContext对象也具有相同的环境。这意味着用配置了AuthenticationSource的LdapContextSource包装PoolingContextSource无法按预期工作。池将使用第一个用户的凭据填充,并且除非需要新的连接,否则后续上下文请求不会为指定线程的AuthenticationSource用户填满。