user710818
user710818

Reputation: 24248

Java Spring bean with private constructor

Is it possible in Spring that a class for bean doesn't have a public constructor but only a private one? Will this private constructor be invoked when the bean is created?

Upvotes: 54

Views: 46336

Answers (6)

GnanaJeyam
GnanaJeyam

Reputation: 3170

Yes ! Spring can access private constructor. It will works internally like below code.

 try {
    Class clazz = Class.forName("A"); // A - Fully qualified class name
    Constructor constructor[] = clazz.getDeclaredConstructors();
    constructor[0].setAccessible(true);
    A a = (A) constructor[0].newInstance();
 }
 catch (Exception e) {
        e.printStackTrace();
 }

Upvotes: 1

pradhap paranthaman
pradhap paranthaman

Reputation: 1

Spring will never call private constructor as Bean scope. If do it will through the below error.

Common causes of this problem include using a final class or a non-visible class. Nested exception is

java.lang.IllegalArgumentException: No visible constructors in class.

Upvotes: 0

Ashish Ani
Ashish Ani

Reputation: 332

Yes, Private constructors are invoked by spring. Consider my code:

Bean definition file:

<bean id="message" class="com.aa.testp.Message">
        <constructor-arg index="0" value="Hi Nice"/>
    </bean>

Bean class:

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);
    }

}

The above code works fine. Hence, spring invoked the private constructor.

Upvotes: 3

Ashkan Aryan
Ashkan Aryan

Reputation: 3534

You would normally have a static factory method in such beans, you can specify that method for spring to get an instance of that bean. See 3.3.1.3 here. This is the way it's recommended by Spring, rather than going against visibility restrictions.

Upvotes: 0

KevinS
KevinS

Reputation: 7875

Yes, Spring can invoke private constructors. If it finds a constructor with the right arguments, regardless of visibility, it will use reflection to set its constructor to be accessible.

Upvotes: 89

Matthew Farwell
Matthew Farwell

Reputation: 61705

You can always use a factory method to create beans rather than relying on a default constructor, from The IoC container: Instantiation using an instance factory method:

<!-- 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"/>

This has the advantage that you can use non-default constructors for your bean, and the dependencies for the factory method bean can be injected as well.

Upvotes: 3

Related Questions