【问题标题】:Getting Spring beans by method invocation vs new operator通过方法调用与新运算符获取 Spring bean
【发布时间】:2026-01-22 18:00:02
【问题描述】:

我对这个小话题感到困惑。我在某处读到,如果一个类用@Component 注释,它是spring 管理的bean,只要需要,spring 就会提供它。我将它与 bean 的范围混淆了。让我解释一下:

假设一个类

@Component
public class Example{ }

如果我在其他类中使用new Example() 实例化这个类,容器是否会一直为我提供相同的示例对象?还是每次都会返回我新的对象?

令人困惑的部分来了:

如果在同一个班级我有两个这样的豆子:

@Component
public class Example {
    @Bean DataSource sqlDataSource() {
         // some logic
    }
    @Bean @Scope("prototype") SomeObject getSomeObject() {
         return new SomeObject(sqlDataSource()); //**
    }

}

在这种情况下会发生什么?每次请求 SomeObject bean 时,sqlDataSource() 方法调用都会一次又一次地返回相同的对象,还是每次请求 SomeObject 时都会返回新的 DataSource 实例?

请帮忙。

【问题讨论】:

    标签: java spring


    【解决方案1】:

    @Bean 是一个方法级注解,指示 Spring 在调用该方法时创建一个 bean。这意味着具有与 XML 配置中的标记相同的功能。

    这个注解必须在 @Configuration 注解的类中使用,否则如果你从另一个方法调用该方法,它将是一个普通的 java new 操作,而不是 spring 的。看到这个帖子 --> @Bean inside class with @Configuration and witout it

    牢记这一点 new SomeObject(sqlDataSource());将等于 new SomeObject(new SqlDataSource());

    如果您使用 @Configuration 注释 Example 将会发生的是,您将始终获得具有相同 sqlDataSource 对象的新 SomeObject 实例,这意味着 Spring 将只创建一个 sqlDataSource 因为它是单例的。

    【讨论】:

      【解决方案2】:
      @Bean DataSource sqlDataSource() {
           // some logic
      }
      

      这定义了 DataSource 的单例实例。因此,每次您请求 SomeObject 的实例时,都会创建一个新的 SomeObject(虽然它是在原型范围内定义的),但它们都将共享同一个 DataSource 对象(因为它是一个单例 bean)。

      【讨论】: