开发者

Spring/LDAP - Invoking setter methods in beans configuration

I am writing a Spring LDAP application and I have to set the authentication strategy for my ContextSource. I would like to do this in my beans XML file. The JavaDoc for ContextSource says that it has a setter method called

setAuthenticationStrategy(
    DirContextAuthenticationStrategy authenticationStrategy
)

To invoke this setter from my beans file, is the following XML sufficient?

<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>

That is to say, what exactly determines the invocation of the method setAuthenticationStrategy? Is it that my property name is authenticationStrategy? Does Spring automatically translate property names to the appropriate setter method?


Actually, you misunderstood the meaning of the word 'property' in the JavaBean context.

Bean Properties vs Fields

The JavaBeans standard (which Spring follows closely) defines a Bean property as something that has a Getter method and / or a Setter method that follows a certain naming convention:

for a property 'Bar foo', either the getter Bar getFoo() (or isFoo() for boolean properties) or the setter setFoo(Bar) must be present (or both), but there does not have to be a field named "foo". Per convention, there usually is a field with the same name as the property, but it's by no means required.

E.g. the following class (which conforms to the JavaBeans standard) has a bean property "foo" of type Integer, although the underlying field is called iAmNotFoo and is of type String.

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

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

We can test this assumption with the following code:

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());
    }
}

Output:

Property: foo, type: class java.lang.Integer
Field: iAmNotFoo, type: class java.lang.String

Properties in Spring

As I said above, Spring uses this exact mechanism to set properties. So when you configure a bean like this

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

"foo" refers to the bean property "foo" and hence to the setter setFoo()

Which makes constructs like the following possible:

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);
    }
}

You can wire this as follows

<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>

As you can see, the setter methods are relevant to Spring, not the actual fields.

So, in JavaBeans speak: Field != Property, although in most cases a field of the same type and name as the property exists.


Your suspicion is correct: Spring translates property names to setter methods.

The bean you are using as the argument is of type DefaultTlsDirContextAuthenticationStrategy, and the method accepts an object of type DirContextAuthenticationStrategy, so DefaultTlsDirContextAuthenticationStrategy must be a subclass of implementor of DirContextAuthenticationStrategy.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜