背景
比如下面的 AService 为什么beanName是 AService ,首字母为什么没有小写。小写反而获取不到。
@Component
public class AService {
}
...
applicationContext.getBean("AService")
源码逻辑
protected String buildDefaultBeanName(BeanDefinition definition) {
String beanClassName = definition.getBeanClassName();
Assert.state(beanClassName != null, "No bean class name set");
// shortClassName 类名
String shortClassName = ClassUtils.getShortName(beanClassName);
// 首字母小写 (除前两个字母都大写之外)
// 以前的版本用的是这种方法
// Introspector.decapitalize(shortClassName);
/** * 条件断点 "AService".toLowerCase().equals(shortClassName.toLowerCase())
*/
return StringUtils.uncapitalizeAsProperty(shortClassName);
}
public static String uncapitalizeAsProperty(String str) {
// !hasLength(str) 为空 null 或 "" // (str.length() > 1 && Character.isUpperCase(str.charAt(0)) && Character.isUpperCase(str.charAt(1))) 长度大于1,且前两个字母大写
// 即:有以下两种情况的返回类名
// 1. 为空 null 或 "" // 2. 长度大于1,且前两个字母大写 (比如: 类名 AService 则返回 AService ,而不是 aService)
if (!hasLength(str) || (str.length() > 1 && Character.isUpperCase(str.charAt(0)) &&
Character.isUpperCase(str.charAt(1)))) {
return str;
}
return changeFirstCharacterCase(str, false);
}
调试截图
这里的 beanName 是 AService

这里可以看到具体的判断逻辑

规则总结
Java中 beanName 和数据库字段名字,不要让前两个字段都是大写。框架会对这进行判断然后特殊处理。 比如这里的 beanName 。
注
spring 不同的版本,可能代码位置不同,但是逻辑相同。