Java Spring bean с приватным конструктором
Возможно ли весной, что класс для bean-компонента не имеет открытого конструктора, а только частного? Будет ли этот частный конструктор вызываться при создании bean-компонента? Благодарю.
6 ответов
Да, Spring может вызывать частные конструкторы. Если он находит конструктор с правильными аргументами, независимо от видимости, он использует отражение, чтобы установить свой конструктор доступным.
Вы всегда можете использовать фабричный метод для создания bean-компонентов, а не полагаться на конструктор по умолчанию из контейнера IoC: создание экземпляра с использованием метода фабрики экземпляра:
<!-- the factory bean, which contains a method called createInstance() -->
<bean id="serviceLocator" class="com.foo.DefaultServiceLocator">
<!-- inject any dependencies required by this locator bean -->
</bean>
<!-- the bean to be created via the factory bean -->
<bean id="exampleBean"
factory-bean="serviceLocator"
factory-method="createInstance"/>
Преимущество этого заключается в том, что вы можете использовать конструкторы не по умолчанию для вашего bean-компонента, а также можно вводить зависимости для bean-компонента фабричного метода.
Да, частные конструкторы вызываются весной. Посмотрите на мой код:
Файл определения бина:
<bean id="message" class="com.aa.testp.Message">
<constructor-arg index="0" value="Hi Nice"/>
</bean>
Класс бобов:
package com.aa.testp;
public class Message {
private String message;
private Message(String msg) {
// You may add your log or print statements to check execution or invocation
message = msg;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public void display() {
System.out.println(" Hi " + message);
}
}
Приведенный выше код работает нормально. Следовательно, весна вызвала частного конструктора.
Да! Spring может получить доступ к частному конструктору. Это будет работать внутри, как показано ниже.
try{
Class c= Class.forName("A"); // A - className
Constructor c1[]=c.getDeclaredConstructors();
c1[0].setAccessible(true);
A a= (A)c1[0].newInstance();
}
catch (Exception e){
e.printStackTrace();
}
Spring никогда не будет вызывать частный конструктор как область действия Bean. Если это произойдет, это приведет к ошибке ниже.
Общие причины этой проблемы включают использование последнего класса или невидимого класса; вложенное исключение - java.lang.IllegalArgumentException: в классе нет видимых конструкторов.
Обычно в таких bean-компонентах есть статический метод фабрики, вы можете указать этот метод для spring, чтобы получить экземпляр этого bean-компонента. Смотрите 3.3.1.3 здесь. Это способ, который рекомендуется Spring, вместо того, чтобы идти против ограничений видимости.