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, вместо того, чтобы идти против ограничений видимости.

Другие вопросы по тегам