Создание экземпляров объектов Spring vs Guice

#java #spring #dependency-injection #guice

#java #spring #внедрение зависимостей #guice

Вопрос:

Недавно я начал изучать Spring. Поскольку я новичок в Spring, мне приходит в голову несколько вопросов. Одним из них является следующее:

Как указано здесь, «Все компоненты создаются, как только конфигурация spring загружается container. org.springframework.context .Контейнер ApplicationContext следует методологии предварительной загрузки «. Ссылка

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 о создании нового объекта?

Комментарии:

1. Давайте посмотрим вашу конфигурацию. По умолчанию компоненты Spring являются одиночными.

2. Также потребуется этот HelloService класс.

Ответ №1:

1 — Означает ли это, что все объекты, созданные с помощью Spring ApplicationContext, являются одиночными?

Нет. Но область Spring по умолчанию singleton равна. Если вам нужна другая область, вы должны явно объявить ее в конфигурации компонента. В конфигурации Java вы делаете это с @Scope помощью аннотации. При настройке XML вы делаете это с <bean> scope помощью атрибута. Среди других способов…

2- Не создает ли это некоторых проблем, когда Spring создает объекты, которые сохраняют некоторое состояние?

Вы всегда можете объявить другую область, так что нет.

3- Как сообщить Spring о создании нового объекта?

Это зависит от области видимости. Если область prototype действия равна, то вызов ApplicationContext#getBean(String) будет каждый раз давать вам новый экземпляр. Если ваш компонент является a singleton , то вы всегда будете получать один и тот же экземпляр.

Обратите внимание, что у вас может быть несколько компонентов одного и того же типа, но с разными областями. Например,

 <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 везде.

Комментарии:

1. «Обратите внимание, что у вас может быть несколько компонентов одного типа, но с разными областями» можете ли вы привести пример?