Reputation: 12123
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?
Upvotes: 3
Views: 5877
Reputation: 298818
Actually, you misunderstood the meaning of the word 'property' in the JavaBean context.
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
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.
Upvotes: 5
Reputation: 4869
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
.
Upvotes: 2