2016-05-11 2 views
3

Я читаю JavaBean specification, но я не могу найти предложение, в котором четко указано, что у компонента bean должен быть конструктор по умолчанию. Так или нет?Должен ли bean иметь конструктор по умолчанию?

+0

Некоторые API, такие как JPA или JAXB, ожидают его, но это не строгое требование. –

+0

Это не обязательно. С одной стороны, фреймворки bean должны распознавать конструктор, аннотированный с помощью [@ConstructorProperties] (http://docs.oracle.com/javase/8/docs/api/java/beans/ConstructorProperties.html). – VGR

ответ

6

Вы можете посмотреть на википедию о Java Bean:

https://en.wikipedia.org/wiki/JavaBeans

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

EDIT: Если бы мы должны были разработать о причинах, желательно не-арг конструктор (но, как правило, не насильственные), ниже одна из причин:

рамки CDI обычно имеет два способа инъекционные зависимых в вашем компоненте:

Впрыск конструктора: Если вы явно определили зависимости вашего компонента в его конструкторе. Пример (весна):

@Component 
public class SuchBean { 
    private MuchDependency muchDependency; 

    @Autowired 
    public SuchBean(MuchDependency muchDependency){ 
     this.muchDependency = muchDependency; 
    } 

} 

сеттер/инъекции Отражение: Где вы не обязательно вводили никаких зависимостей через конструктор, но зависимостей инъецируют средой CDI либо с использованием отражения или сеттеров. Пример:

@Component 
public class SuchBean { 
    // this dep doesn't have a setter, so the CDI will use reflection to set it 
    @Autowired private MuchDependencyWithReflection muchDependencyWithReflection; 
    // this dep has a setter so the CDI will use the setter to set it 
    @Autowired private MuchDependencyWithSetter muchDependencyWithSetter; 

    public void setMuchDependencyWithSetter(MuchDependencyWithSetter muchDependencyWithSetter){ 
     this.muchDependencyWithSetter = muchDependencyWithSetter; 
    } 
} 

В приведенном выше примере, если вы явно не определено не-арг конструктор, конечно, вы знаете, Java предоставляет его для вас (потому что каждый класс, который не имеет каких-либо конструктор явно определенный, просто имеет автоматически предоставленный конструктор no-args). Так что все будет хорошо и денди, пока вы не решите определить свой собственный конструктор с аргументами:

@Component 
public class SuchBean { 
    // this dep doesn't have a setter, so the CDI will use reflection to set it 
    @Autowired private MuchDependencyWithReflection muchDependencyWithReflection; 
    // this dep has a setter so the CDI will use the setter to set it 
    @Autowired private MuchDependencyWithSetter muchDependencyWithSetter; 

    public SuchBean(String nonDefaultConstuctorArg){ 
     System.out.println(nonDefaultConstuctorArg); 
    } 

    public void setMuchDependencyWithSetter(MuchDependencyWithSetter muchDependencyWithSetter){ 
     this.muchDependencyWithSetter = muchDependencyWithSetter; 
    } 
} 

В приведенном выше примере это не очевидно, но любая структура, зависимость будет жаловаться и не сможет создать его экземпляр, потому что на самом деле, когда вы используете инъекции отражения/сеттера, каркас делает:

Constructor.newInstance(); 

за кулисами, а затем впрыскивает зависимости. Однако, поскольку вы просто сделали свой класс не конструктором по умолчанию, newInstance() без args не будет работать. Следовательно, в этом случае вам нужен конструктор args по умолчанию. Подводя итог:

  • Если вы используете инъекцию конструктора, вам не нужен конструктор no-args.
  • Если вы используете инъекцию отражения/сеттера, вам нужно использовать конструктор no-args .
  • Поскольку хороший код должен иметь хорошие соглашения, стандарт JavaBeans «подталкивает» вас к тому, что везде конструктор no-args по умолчанию имеет стандартный, обычный код, который можно использовать в различных рамках и быть читаемым/понятным/поддерживаемым из-за его стандартизации.
+0

wikipedia предоставляет источник или ссылку для этого правила? – wero

+0

@wero так не думаю :) –

0

Не нужно (некоторые рамки требуется закуска), но это хорошая практика

1

боба не нужно иметь конструктор по умолчанию.Просто потому, что спецификация не определяет это требование.

Дополнительно глава 10,3 Инстанцирования боба переговоры о получении боба экземпляров:

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

Эта стратегия реализована по адресу Beans.instantiate: Он ищет сериализованный компонент (специальный ресурс Java). Если он не находит его, он пытается создать экземпляр компонента через Class.newInstance. Но этот механизм ясно показывает, что разработчики spec думали о предоставлении универсального метода для получения экземпляров bean, у которых нет конструктора по умолчанию.

Смежные вопросы