【问题标题】:Spring Boot - creating Bean as Singleton in IOC containerSpring Boot - 在 IOC 容器中将 Bean 创建为 Singleton
【发布时间】:2020-02-05 13:59:26
【问题描述】:

Bean 创建应该是 Spring 容器中的 Singleton,对吗?我正在使用注释将 Spring 配置文件迁移到 Spring Boot。我有下面的代码,但似乎每次在另一个 bean 创建中使用它时都会调用“mySingletonBean()”。我的理解是 @Bean 注释默认应该是 Singleton 。我是否正确地创建了我的 Bean?

@Bean
public SomeBean mySingletonBean() {
  SomeBean mybean = new SomeBean();
  mybean.setName = "Name";
  return mybean;
}

@Bean 
public Bean1 bean1() {
  Bean1 bean1 = new Bean1();
  bean1.setBean(mySingletonBean());
  return bean1;
}

@Bean 
public Bean2 bean2() {
  Bean2 bean2 = new Bean2();
  bean2.setBean(mySingletonBean());
  return bean2;
}


【问题讨论】:

  • 方法调用将被代理到@Configuration。类并导致相同的实例。但是,这仅适用于 @Configuration 类而不是 `@Component 类。
  • 我对你的问题有点困惑。您是否观察到创建了两个不同的 SomeBean 实例,或者您是否担心调用该方法可能/将导致重复 bean 创建?

标签: java spring spring-boot ioc-container


【解决方案1】:

Spring 正在代理您的应用程序上下文类,并处理所有与上下文相关的内容,例如 bean 的实例化、缓存等。

运行这个小测试,随意调试看看配置类变成了什么类:

package stackoverflow;

import java.util.Arrays;
import java.util.Date;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import static org.junit.Assert.assertTrue;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = Test.MyContext.class)
public class Test {

    @Autowired
    private ApplicationContext applicationContext;
    @Autowired
    @Qualifier("myStringBean")
    private String myStringBean;
    @Autowired
    private SomeBean someBean;

    @Configuration
    static class MyContext {

        @Bean
        public String myStringBean() {
            return String.valueOf(new Date().getTime());
        }

        @Bean
        public SomeBean mySomeBean() {
            return new SomeBean(myStringBean());
        }

    }

    @org.junit.Test
    public void test() {
        assertTrue(myStringBean == applicationContext.getBean("myStringBean"));
        assertTrue(myStringBean == someBean.getValue());
        System.out.println(Arrays.asList(applicationContext.getBean("myStringBean"), myStringBean, someBean.getValue()));
    }

    static class SomeBean {

        private String value;

        public SomeBean(String value) {
            this.value = value;
        }

        public String getValue() {
            return value;
        }
    }

}

【讨论】:

    【解决方案2】:

    Spring Boot 是智能框架,方法mySingletonBean() 只会启动一次,不用担心。你可以启动调试模式看看。

    【讨论】:

      猜你喜欢
      • 2011-04-05
      • 2019-09-08
      • 2016-12-15
      • 1970-01-01
      • 1970-01-01
      • 2015-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多