如果问题还不够清楚,我的歉意,但我将尝试在下面进行解释:
我有一个称为 cricketcoach.java 的类
public class CricketCoach implements Coach {
private FortuneService fortuneService;
......
......
public void setFortunaeService(FortuneService fortuneService) {
System.out.println("Spring calling the setter method");
this.fortuneService = fortuneService;
}
.......
.......
}
我在 applicationContext.xml 文件中具有弹簧配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean
id = "myFortuneService"
class = "com.example.basicspring.dependencyinjection.HappyFortuneService">
</bean>
<bean
id = "myCricketCoach"
class = "com.example.basicspring.dependencyinjection.CricketCoach">
<property name="fortuneService" ref="myFortuneService"/>
</bean>
</beans>
我有以下驱动程序类
public class HelloSpringApp {
public static void main(String[] args) {
ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Coach theCoach = classPathXmlApplicationContext.getBean("myCricketCoach", Coach.class);
System.out.println(theCoach.getDailyWorkout());
System.out.println(theCoach.getDailyFortune());
classPathXmlApplicationContext.close();
}
}
在 applicationContext.xml 中,我故意给出了错误的属性名称,以查看Spring抛出的例外。
以下例外是由弹簧抛出的
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myCricketCoach' defined in class path resource [applicationContext.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'fortuneService' of bean class [com.example.basicspring.dependencyinjection.CricketCoach]: Bean property 'fortuneService' is not writable or has an invalid setter method. Did you mean 'fortunaeService'? // Interestingly Spring guesses the correct method name
这里有趣的是,春天猜测实际的方法名称正确,并建议此Did you mean 'fortunaeService'?
但是,当我更改 cricketcoach 类中的方法名称时,从 setFortunaeService
到 setXYZ
public void setXYZ(FortuneService fortuneService) {
System.out.println("Spring calling the setter method");
this.fortuneService = fortuneService;
}
春季不再能够猜测正确的方法并显示以下错误消息
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myCricketCoach' defined in class path resource [applicationContext.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'fortuneService' of bean class [com.example.basicspring.dependencyinjection.CricketCoach]: Bean property 'fortuneService' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
我想知道的是Spring如何能够准确地猜测属性名称,但不能第二次这样做。
Spring背后的逻辑到底是什么才能正确猜出该方法的名称?
感谢您的时间
逻辑(至少在我正在查看的春季版本中(可以在课堂上找到:
org.springframework.beans.propertymatches
/**
* Generate possible property alternatives for the given property and
* class. Internally uses the <code>getStringDistance</code> method, which
* in turn uses the Levenshtein algorithm to determine the distance between
* two Strings.
* @param propertyDescriptors the JavaBeans property descriptors to search
* @param maxDistance the maximum distance to accept
*/
private String[] calculateMatches(PropertyDescriptor[] propertyDescriptors,
int maxDistance) {
List<String> candidates = new ArrayList<String>();
for (PropertyDescriptor pd : propertyDescriptors) {
if (pd.getWriteMethod() != null) {
String possibleAlternative = pd.getName();
if (calculateStringDistance(this.propertyName, possibleAlternative)
<= maxDistance) {
candidates.add(possibleAlternative);
}
}
}
Collections.sort(candidates);
return StringUtils.toStringArray(candidates);
}
正如评论所指出的那样,使用以下算法进行替代方案:
https://en.wikipedia.org/wiki/levenshtein_distance
和setxyz将太远而无法考虑。