Spring bean命名规则

Spring bean命名规则

只有首字母大写

@Controller
public class UserController {
    public void SayHello(){
        System.out.println("do SayHello()");
    }
}
public class Test {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(UserController.class);

        // 指定bean名
        UserController bean = context.getBean("", UserController.class);

        bean.SayHello();
    }
}

报错:org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named '' available

public class Test {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(UserController.class);

        // 指定bean名
        UserController bean = context.getBean("UserController", UserController.class);

        bean.SayHello();
    }
}

报错org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'UserController' available

public class Test {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(UserController.class);

        // 指定bean名
        UserController bean = context.getBean("userController", UserController.class);

        bean.SayHello();
    }
}

打印do SayHello()
bean名是小驼峰命名法

前两个首字母大写

@Controller
public class SController {
    public void SayHello(){
        System.out.println("do SayHello()");
    }
}

但是当看运行结果的时候,却发现这样小驼峰的形式行不通了

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(UserController.class);

        // 指定bean名
        SController bean = context.getBean("sController", SController.class);

        bean.SayHello();
    }

org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'sController' available

但是当我在将名称改回【类名】的时候,却发现又可以运行了

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(UserController.class);

        // 指定bean名
        SController bean = context.getBean("SController", SController.class);

        bean.SayHello();
    }

do SayHello()

原理探究

找到Spring中生成beanName的代码

public class AnnotatedBeanDefinitionReader {
    
    private BeanNameGenerator beanNameGenerator = AnnotationBeanNameGenerator.INSTANCE;

    private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
            @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
            @Nullable BeanDefinitionCustomizer[] customizers) {

        // 忽略 多余代码
        String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
        // 忽略 多余代码
        BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
         // 忽略 多余代码
        BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
    }
}

public interface BeanNameGenerator {

    String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry);

}

public class AnnotationBeanNameGenerator implements BeanNameGenerator {

    public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
        if (definition instanceof AnnotatedBeanDefinition) {
            String beanName = this.determineBeanNameFromAnnotation((AnnotatedBeanDefinition)definition);
            if (StringUtils.hasText(beanName)) {
                return beanName;
            }
        }

        return this.buildDefaultBeanName(definition, registry);
    }
    protected String buildDefaultBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
        return this.buildDefaultBeanName(definition);
    }

    protected String buildDefaultBeanName(BeanDefinition definition) {
        String beanClassName = definition.getBeanClassName();
        Assert.state(beanClassName != null, "No bean class name set");
        String shortClassName = ClassUtils.getShortName(beanClassName);
        return Introspector.decapitalize(shortClassName);
    }
}
    public static String decapitalize(String name) {
        if (name == null || name.length() == 0) {
            return name;
        }
        // 若是首字母和第二个字母都是大写的话,那就返回原来的名称
        if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) &&
                        Character.isUpperCase(name.charAt(0))){
            return name;
        }
        // 将字符串首先转换成了字符数组,然后再将第一位变成小写
        char chars[] = name.toCharArray();
        chars[0] = Character.toLowerCase(chars[0]);
        return new String(chars);
    }

可以很明显看到,这里是有两种情况,若是首字母和第二个字母都是大写的话,那就返回原来的名称;第二种情况则是将字符串首先转换成了字符数组,然后再将第一位变成小写

总结

通过查看Spring的源码我们进入到了JDK中,经过代码的阅读将Bean的命名转换总结了以下两点

  • 默认情况:使用原类名首字母小写就能读取到Bean对象
  • 特例:如果首字母和第二字母都是大写的情况下,那么Bean名称就是原类名
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值