在Spring中在运行时切换LDAP连接

时间:2015-07-17 14:36:18

标签: java spring spring-security dependency-injection spring-ldap

我是春天新手。我的基于Spring的Web应用程序的管理员希望从Web界面配置设置,以便用户可以使用他们的公司用户名和密码对LDAP服务器进行身份验证。

无需重新启动应用程序即可更改LDAP设置。这可能发生在“迁移”过程中。无论什么原因。我有几个bean,需要在管理员保存LDAP服务器的新设置后刷新:

<bean id="ldapServer" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
    <constructor-arg>
        <list>
            <value>${ldap.url1}</value>
            ...
        </list>
    </constructor-arg>
    <constructor-arg value="${ldap.basedn}"</constructor-arg>
    <property name="referral" value="${ldap.referral}" />
    <property name="baseEnvironmentProperties">...</property>
    <property name="userDn" value="${ldap.username}" />
    <property name="password" value="${ldap.password}" />
</bean>

我正在使用Springframework 3.1.2。问题是,有构造函数参数,我想要更改它,而不会影响其他正在运行的作业。我尝试使用Scoped代理,但还没有取得多大成功:

<bean id="ldapServer" scope="prototype" ...>
    <aop:scoped-proxy/>

通过运行这段代码使用原型范围时,我成功地让ldapServer重新实例化了:

@Controller
public class LDAPSettingsController implements ApplicationContextAware {
    public ModelAndView handleRequest(...) {
        DefaultSpringSecurityContextSource ldap;
        ldap = context.getParentBeanFactor().getBean("ldapServer");

        System.out.println(ldap.hashCode());

        return new ModelAndView(new RedirectView('login.jsp'));
    }
    ...
}

这里的范围和代理是可行的,还是Spring中的另一种机制,可以将配置更改反映到正在运行的程序实例中?

更新:澄清问题。 更新:AOP代理的根问题是遵循根异常:

java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given

1 个答案:

答案 0 :(得分:0)

proxy-target-class="false"属性添加到<aop:scoped-proxy/>标记有用。我创建了一个新的范围,它比原型更好 - 它在设置更新时销毁bean。现在我在beans.xml中有这个:

<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
  <property name="scopes">
    <map>
      <entry key="ldap">
        <ref bean="ldapScope" />
      </entry>
    </map>
  </property>
</bean>

<bean id="ldapScope" class="com.myapp.SettingsScope" />

<bean id="ldapServer" scope="ldap" ...>
    <aop:scoped-proxy proxy-target-class="false"/>
    <constructor-args>
      <list><value>${ldap.url1}</value> .. </list>
    </constructor-args>
    ...
</bean>

我还有一个用于LDAP设置的控制器,我将ldapScope注入其中,并且我调用一个方法来销毁当前的生命周期对象并每次启动一个新的生命周期,用户按下应用按钮。

PS:不确定我是否以正确的方式处理生命周期“重新启动” - 人们寻找自动启动bean并在事件发生后启动它们(即:设置 - &gt;应用)