3

我正在编写一个 Spring LDAP 应用程序,我必须为我的 ContextSource 设置身份验证策略。我想在我的 beans XML 文件中执行此操作。ContextSource的JavaDoc说它有一个称为 setter 的方法

setAuthenticationStrategy(
    DirContextAuthenticationStrategy authenticationStrategy
)

要从我的 beans 文件中调用此 setter,以下 XML 是否足够?

<bean id="authStrategy"
    class="org.springframework...DefaultTlsDirContextAuthenticationStrategy">
 ...
</bean>

<bean id="contextSource"
    class="org.springframework.ldap.core.support.LdapContextSource">

    <property name="url" ... />
    <property name="base" ... />
     ...
    <property name="authenticationStrategy" ref="authStrategy" /> 
</bean>

也就是说,究竟是什么决定了方法的调用setAuthenticationStrategy?是我的财产名称authenticationStrategy吗?Spring 是否会自动将属性名称转换为适当的 setter 方法?

4

2 回答 2

5

实际上,您误解了 JavaBean 上下文中“属性”一词的含义。

Bean 属性与字段

JavaBeans 标准(Spring 密切遵循)将 Bean 属性定义为具有遵循特定命名约定的 Getter 方法和/或 Setter 方法的东西:

对于属性“Bar foo”,getter Bar getFoo()(或isFoo()布尔属性)或 settersetFoo(Bar)必须存在(或两者都存在),但不必存在名为“foo”的字段。按照惯例,通常有一个与属性同名的字段,但这绝不是必需的。

例如,下面的类(符合 JavaBeans 标准)有一个整数类型的 bean 属性“foo”,尽管底层字段被调用iAmNotFoo并且是字符串类型。

public class Dummy {
    private String  iAmNotFoo;
    public Integer getFoo() {
        return  Integer.valueOf(this.iAmNotFoo);
    }

    public void setFoo(final Integer foo) {
        this.iAmNotFoo = foo.toString();
    }
}

我们可以使用以下代码来测试这个假设:

public static void main(final String[] args) throws Exception {
    for (final PropertyDescriptor descriptor :
        Introspector
            .getBeanInfo(Dummy.class, Object.class)
            .getPropertyDescriptors()) {
        System.out.println(
            "Property: "
            + descriptor.getName()
            + ", type: "
            + descriptor.getPropertyType()
        );
    }
    for (final Field field : Dummy.class.getDeclaredFields()) {
        System.out.println(
            "Field: " 
            + field.getName() 
            + ", type: " 
            + field.getType());
    }
}

输出:

属性:foo,类型:class java.lang.Integer
字段:iAmNotFoo,类型:class java.lang.String

春季房产

正如我上面所说,Spring 使用这种精确的机制来设置属性。所以当你像这样配置一个bean时

<bean class="Dummy">
    <property name="foo" value="123" />
</bean>

“foo”指的是 bean 属性“foo”,因此指的是 settersetFoo()

这使得如下构造成为可能:

public class Dummy2 {
    private List<String> foos;
    public void setFoos(List<String> foos) {
        this.foos = foos;
    }
    public void setFoo(String foo){
        this.foos = Collections.singletonList(foo);
    }
}

您可以按如下方式接线

<bean class="Dummy2">
    <!-- either set a single value -->
    <property name="foo" value="123" /> 
    <!-- or a list of values -->
    <property name="foos"> 
        <util:list>
            <value>Abc</value>
            <value>Xyz</value>
            <value>123</value>
            <value>789</value>
        </util:list>
    </property>
</bean>

如您所见,setter 方法与 Spring 相关,而不是实际字段。

因此,在 JavaBeans 中说:Field != Property,尽管在大多数情况下存在与属性相同类型和名称的字段。

于 2011-01-21T20:43:57.077 回答
2

您的怀疑是正确的:Spring 将属性名称转换为 setter 方法。

您用作参数的 bean 是 type 的DefaultTlsDirContextAuthenticationStrategy,并且该方法接受 type 的对象DirContextAuthenticationStrategy,因此DefaultTlsDirContextAuthenticationStrategy必须是 implementationor 的子类DirContextAuthenticationStrategy

于 2011-01-21T18:13:23.167 回答