【问题标题】:Understanding the instance variable names and the methods to create it using Spring @Bean annotation了解实例变量名称以及使用 Spring @Bean 注解创建它的方法
【发布时间】:2018-08-30 10:45:10
【问题描述】:

我编写了一个简单的 Spring Boot 应用程序,稍后我将对其进行扩展以构建一个 Spring REST 客户端。我有一个工作代码;我试图更改一些实例变量名称和方法名称并四处玩弄。

代码:

@SpringBootApplication
public class RestClientApplication {

public static void main(String[] args) {
    SpringApplication.run(RestClientApplication.class, args);

    try (AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
            RestClientApplication.class)) {
        System.out.println(" Getting RestTemplateBuilder : " + ctx.getBean("restTemplateBuilder"));
        System.out.println(" Getting RestTemplate : " + ctx.getBean("restTemplate"));
    }
}

@Bean
public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
    return restTemplateBuilder.build();
}

@Bean
public CommandLineRunner runner() {
    return args -> { SOP("hello"); }
}

}

观察:

  1. 实例变量名称遵循驼峰式表示法,如 预期的。因此,restTemplate 和 restTemplateBuilder 有效。
  2. 通过restTemplate() 方法创建RestTemplate 实例时,我尝试将参数名称更改为builder。它有效。
  3. 通过 restTemplate() 方法创建 RestTemplate 实例时,我尝试将方法名称更改为随机名称,但出现“没有可用的名为 'restTemplate' 的 bean”的异常。
  4. CommandLineRunner 接口是通过 lambda 表达式实现的。访问 commandLineRunner 会引发异常。

问题

为什么我会看到第 2 点和第 3 点中提到的结果?

【问题讨论】:

    标签: spring spring-boot lambda functional-interface


    【解决方案1】:

    在通过 restTemplate() 方法创建 RestTemplate 实例时, 我尝试将参数的名称更改为 builder。它有效。

    这是因为,默认情况下,弹簧自动装配的类型。所以它搜索类型为RestTemplateBuilder 的bean 并找到它,因此没有错误。

    在通过 restTemplate() 方法创建 RestTemplate 实例时, 我尝试将方法的名称更改为随机名称,然后得到一个 “没有名为 'restTemplate' 的 bean 可用”的例外情况。

    你得到一个异常不是因为你改变了方法名,而是因为这个

    ctx.getBean("restTemplate")
    

    因为默认情况下@Bean 使用方法名称作为 bean 的名称。 (check this)。因此,由您的随机方法返回的 RestTemplate 类型的 bean 的名称是您的随机方法的名称。因此,当您尝试获取名称为 restTemplate 的 bean 时,它会引发异常。

    但是,如果您要自动装配 RestTemplate 类型的 bean,它仍然可以工作,因为 Spring 默认会按类型自动装配,并且它知道 RestTemplate 类型的 bean(名称为随机方法名称)。

    【讨论】:

    • 非常感谢。我已经添加了与此代码相关的第 4 点。请回答。
    • 我对 Spring 核心、Spring 上下文和 DI 有基本的了解。您能否为我提供理解这些概念的推理参考。
    • 最好的方法是尝试不同的东西并找出答案为什么它会这样。不确定您是否可以学习阅读文档的所有内容。但是如果你想阅读 spring 文档是一个很好的起点
    • 我明白#4 为何如此有效。以“运行”的方式访问它。
    • @Bean(name = "restTemplate") 如果你像这样注释 bean,你可以在那里给任何名字,但对象仍然是 restTemplate @sara
    猜你喜欢
    • 2020-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-24
    • 2011-03-16
    • 2020-05-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多