Spring中注解方式的默认beanName生成规则
在Spring中,当我们配置一个bean的时候,可以不指定name,这样的话,Spring会生成一个默认的beanName,一直以为生成规则只是简单的将类名首字母小写,今天看Spring官方文档时,发现还有并不只是如此,还有特殊情况——当类名的首字母和第二个字母是大写的时候,将采用原始的类名作为beanName。下面我们进行分析一下。
原文如下:
With component scanning in the classpath, Spring generates bean names for unnamed components, following the rules above: essentially, taking the simple class name and turning its initial character to lower-case. However, in the (unusual) special case when there is more than one character and both the first and second characters are upper case, the original casing gets preserved. These are the same rules as defined by java.beans.Introspector.decapitalize (which Spring is using here).
大概意思就是说spring在给未命名的组件生成bean name的时候,采用简单的类名并将其初始字符转换为小写。但在特殊情况下,当第一个和第二个字符都是大写的时候,保留原始的形式。而spring使用的就是在java.beans.Introspector类中的decapitalize方法实现的。我们来看看这个方法:
1 /** 2 * Utility method to take a string and convert it to normal Java variable 3 * name capitalization. This normally means converting the first 4 * character from upper case to lower case, but in the (unusual) special 5 * case when there is more than one character and both the first and 6 * second characters are upper case, we leave it alone. 7 * <p> 8 * Thus "FooBah" becomes "fooBah" and "X" becomes "x", but "URL" stays 9 * as "URL". 10 * 11 * @param name The string to be decapitalized. 12 * @return The decapitalized version of the string. 13 */ 14 public static String decapitalize(String name) { 15 if (name == null || name.length() == 0) { 16 return name; 17 } 18 if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) && 19 Character.isUpperCase(name.charAt(0))){ 20 return name; 21 } 22 char chars[] = name.toCharArray(); 23 chars[0] = Character.toLowerCase(chars[0]); 24 return new String(chars); 25 }
从注释可以看出,此方法作用就是将string转换为普通的java变量的方法。而且还举例了例子:
输入 FooBah 输出fooBah,而输入URL输出仍然是URL,此段代码也不难理解,请读者自行阅读。
Spring中注解和XML的不同生成规则: Spring通过核心接口BeanNameGenerator来生成beanName,目前只有2个具体实现类,一个用于注解一个用于XML,而这两种方式生成规则并不相同,XML方式生成规则是:类名+“#”+数字;而注解方式生成规则正是使用调用的上述的decapitalize方法。 例如: a. 注解方式 @Component public class UserService() { ... } 在IoC容器中的beanName是userService b. xml方式 package com.fishblog.service public class UserService() { ... } <bean class="com.fishblog.service.UserService"></bean> 在IoC容器中的beanName是com.fishblog.service.UserService#0