【问题标题】:Switch LDAP connection at runtime in Spring在 Spring 运行时切换 LDAP 连接
【发布时间】:2015-10-07 07:45:37
【问题描述】:

我是春天的新手。我基于 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

【问题讨论】:

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


    【解决方案1】:

    有效的方法是将proxy-target-class="false" 属性添加到&lt;aop:scoped-proxy/&gt; 标记。我创建了一个新范围,它比原型效果更好 - 它会在设置更新时破坏 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 并在此类事件发生后启动它们(即:设置 -> 应用)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-30
      • 1970-01-01
      • 2016-04-13
      • 1970-01-01
      • 1970-01-01
      • 2017-05-14
      • 1970-01-01
      • 2015-01-17
      相关资源
      最近更新 更多