【问题标题】:Spring vs Guice instantiating objectsSpring vs Guice 实例化对象
【发布时间】:2014-06-20 00:44:38
【问题描述】:

我最近开始学习 Spring。由于我是 Spring 新手,我想到了几个问题。其中之一是:

如此处所述“一旦容器加载了 spring 配置,所有 bean 都会被实例化。org.springframework.context.ApplicationContext 容器遵循预加载方法。” LINK

1 - 这是否意味着使用 Spring ApplicationContext 创建的所有对象都是单例?

我创建了这个简单的测试

@Component
public class HelloService {

 private ApplicationContext context;


 public HelloService() {
 }

 @Autowired
 public HelloService(ApplicationContext context) {
  this.context = context;
 }

 public String sayHello() {

  return "Hi";
 }

}

public class HelloApp {
 public static void main(String[] args) {


  ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
  Injector injector = Guice.createInjector(new AbstractModule() {
   @Override
   protected void configure() {
   }
  });
  HelloService helloService1 = context.getBean(HelloService.class);
  System.out.println(helloService1);
  HelloService helloService2 = context.getBean(HelloService.class);
  System.out.println(helloService2);

  HelloService helloService3 = injector.getInstance(HelloService.class);
  System.out.println(helloService3);
  HelloService helloService4 = injector.getInstance(HelloService.class);
  System.out.println(helloService4);

 }
}

输出是

foo.bar.HelloService@191e8b08 // same instance 
foo.bar.HelloService@191e8b08 // same instance

foo.bar.HelloService@6ba67ab5 // different instance 
foo.bar.HelloService@7ec23849 // different instance

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
  <context:annotation-config/>
  <context:component-scan base-package="foo.bar"/>
</beans> // this is mu config bean. 

在 Guice 中,您必须明确表示您希望将此对象实例化为单例。

2- 当 Spring 创建保持某种状态的对象时,这不会产生一些问题吗?

3- 如何告诉 Spring 创建一个新对象?

【问题讨论】:

  • 让我们看看你的配置。 Spring bean 默认是单例的。
  • 也需要 HelloService 类。

标签: java spring dependency-injection guice


【解决方案1】:

1 - 这是否意味着使用 Spring ApplicationContext 创建的所有对象都是单例?

没有。但是 Spring 的默认作用域 singleton。如果您想要不同的范围,则必须在 bean 配置中显式声明它。在 Java 配置中,您可以使用 @Scope 注释来执行此操作。使用 XML 配置,您可以使用 &lt;bean&gt; scope 属性进行配置。除了其他方式...

2- 当 Spring 创建保持某种状态的对象时,这不会产生一些问题吗?

你总是可以声明不同的范围,所以不行。

3- 如何告诉 Spring 创建一个新对象?

这取决于范围。如果作用域是prototype,那么调用ApplicationContext#getBean(String) 每次都会给你一个新的实例。如果您的 bean 是 singleton,那么您将始终获得相同的实例。

请注意,您可以拥有多个相同类型但具有不同范围的 bean。例如,

<bean name="my-proto" class="com.example.Example" scope="prototype" />
<bean name="my-singleton" class="com.example.Example" /> <!-- defaults to singleton -->

以后

(Example) context.getBean("my-proto"); // new instance every time
(Example) context.getBean("my-singleton"); // same instance every time

因此,您可以在某些情况下使用单例,而在其他情况下使用不同的范围。此外,您不必必须在任何地方都使用 Spring。

【讨论】:

  • “请注意,您可以拥有多个相同类型但范围不同的bean”您能举个例子吗?
猜你喜欢
  • 2011-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多