Каков наилучший способ инициализации бина? - PullRequest
10 голосов
/ 17 октября 2008

Весной вы можете инициализировать bean-компонент, вызвав applicationContext.xml для вызова конструктора, или вы можете установить свойства для bean-компонента. Каковы компромиссы между двумя подходами? Лучше иметь конструктор (который обеспечивает выполнение контракта на все необходимое в одном методе) или лучше иметь все свойства (что дает вам гибкость, позволяющую вводить данные только выборочно, например, при модульном тестировании.)

Каковы компромиссы (между написанием компонента, использующего конструктор для определения его начального состояния, или использованием свойств и, возможно, метода afterProperties ())?

Ответы [ 5 ]

15 голосов
/ 17 октября 2008

Я не уверен, что есть «лучший» способ инициализации бина. Я думаю, что у каждого есть свои плюсы и минусы, и в зависимости от ситуации, один или другой может быть уместным. Это, конечно, не исчерпывающий список, но вот несколько вещей, которые следует учитывать.

Использование конструктора позволяет вам иметь неизменный компонент. Неизменяемые объекты хороши, если вы можете вписать их в свой дизайн. Они не требуют копирования, сериализованного доступа или другой специальной обработки между потоками. Если у вас есть сеттеры, ваш объект не является неизменным. Использование конструктора также обеспечивает правильную инициализацию объекта. После завершения конструктора объект является действительным. Если ваш объект требует использования установщиков для его инициализации, возможно, имеется недопустимый объект.

С другой стороны, использование конструкторов часто приводит к проблеме телескопирования. Часто вам понадобится много разных конструкторов, большинство из которых будет надмножеством другого конструктора. Часто это для удобства. Например:

public class Person {
  public Person(String name) { ... }
  public Person(String name, String phone) { ... }
  public Person(String name, String phone, String email) { ... }
}

Одной из альтернатив, которая мне очень нравится, является так называемый «улучшенный» шаблон компоновщика, представленный Джошем Блохом в JavaOne. Вы можете увидеть это в его книге «Эффективная Java, второе издание». Если вы посмотрите на способ использования шаблона, он также решит проблему с методом afterProperties. Шаблон компоновщика гарантирует правильную инициализацию объекта.

Вот еще одно сообщение в блоге, в котором обсуждается шаблон: http://www.screaming -penguin.com / node / 7598

Я не уверен, что это соответствует вашим требованиям к пружине, но в целом я большой поклонник строителей.

3 голосов
/ 17 октября 2008

IMO главное преимущество инжектора конструктора в том, что он совместим с неизменяемостью. Однако, если класс имеет более 3 зависимостей, это требует предоставления конструктора, который принимает большое количество параметров, что является громоздким.

При использовании сеттер-инъекции я предпочитаю использовать аннотацию @PostConstruct для определения метода инициализации. Это предполагает более слабую связь с платформой Spring, чем упомянутый вами метод afterProperties() (на самом деле, я думаю, это afterPropertiesSet()). Другим вариантом является атрибут метода init элемента <bean>.

2 голосов
/ 17 октября 2008

Я не знаю версию, которую вы сейчас используете, но если это Spring 2.5, вы также можете рассмотреть возможность использования аннотации @Autowired для некоторых случаев. Это грубое работает только для ссылок на другие bean-компоненты, а не для Strings и т. Д., Как в примере lycony.

Это экономит ваше бремя создания сеттеров и / или конструкторов и много настроек. Маленький пример:

public class MyPersonBean {
  @Autowired
  private PersonManager personManager;

  public void doSomething() {
    this.personManager.doSomething();
  }
}

И в вашем конфигурационном файле:

<context:annotation-config/>

Автопроводка выполняется по типу, поэтому, если у вас есть bean-компонент типа PersonManager, он внедрит его в аннотированное поле. Если у вас есть больше бинов такого типа, вы можете использовать аннотацию @Qualifier, чтобы отличать их друг от друга ...

Более подробную информацию об автопроводке можно найти в справочной документации Spring

Я начал использовать @Autowired в сочетании с компонентным сканированием в моем предыдущем проекте, и я должен сказать, что избавился от более чем 90% моих файлов конфигурации Spring.

0 голосов
/ 22 января 2009

Вы также можете использовать @Resource для автоматической передачи вместо @Autowired, это работает как autowire byName, поэтому вам не нужно беспокоиться, если есть больше бинов с тем же типом (ofc, вы также можете обработать это с помощью @Qualifier, но я бы порекомендовал только описать характеристику боба). От вашего варианта использования действительно зависит, какой путь будет наилучшим, поэтому вы должны оценить его для вашей ситуации и принять решение после.

0 голосов
/ 18 октября 2008

Компромиссы:

Конструктор: Выгоды: Может быть очень просто, особенно с тремя или менее свойствами для инициализации. Один выстрел, нет / минимальная дополнительная конфигурация для беспокойства.

Недостатки: Несколько конструкторов должны быть созданы для нескольких ситуаций Конструкторы не наследуются, поэтому классы должны вызывать super () и предоставлять дублирующие конструкторы, чтобы разрешить предыдущее поведение.

сеттеры: Выгоды: Дети наследуют сеттеры, поэтому свойства могут быть легко переопределены, чтобы влиять на поведение после построения. Несколько свойств могут быть заданы унифицированно без поиска различных сигнатур методов (соглашения JavaBeans)

Недостатки: Каждый установщик должен вызываться явно для каждого свойства. Приводит к некоторым классам с явно установленным большим количеством свойств.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...