logo

Spring Dependency Injection With Factory Method


Show

In the Spring framework, we can inject the dependency in the bean using the factory method. A Factory method is a method that returns an instance of a class. It will help you in creating just a single instance of a class. In Spring, beans are by default singleton in scope within the Spring container. In case of having a single java class or a factory class with a static method, if there is a need to use that class within the Spring framework to ensure that only a single instance is created, which is a singleton within the scope of JVM as well as of Spring container, in that case, it is required to use the factory-method attribute of the bean element in the Spring framework.

Factory methods for injecting the dependency should be used in the "@Configuration" classes. In the Factory method of dependency injection, we can use two attributes of the bean element which are listed below:

Factory-method:

It represents the factory method that will be called to inject the bean.

Factory-bean:

It is used to represent the reference of the bean through which the factory method will be called. This attribute is used in the case of a non-static factory method.

The code that mentioned a Factory method is:

public class A {  
public static A getA(){//factory method  
    return new A();  
}  
} 

Factory Method Types

There are three types of Factory methods which are described below:

  • A static factory method that returns an instance of its own class. It is used in singleton classes such as:
<bean id="a" class="com.intellinuts.A" factory-method="getA"></bean>
  • A static factory method that returns an instance of another class. It is known as the used instance that is decided at the runtime.
<bean id="b" class="com.intellinuts.A" factory-method="getB"></bean> 
  • A non-static factory method is one that returns an instance of another class. It is also called an instance factory method. Its used instance is not known and decided at runtime. In the case of a non-static factory method, you will be required to use the factory-bean attribute along with the factory-method attribute.

A simple code that mentioned a non-static factory method is:

<bean id="a" class="com.intellinuts.A"></bean>  
<bean id="b" class="com.intellinuts.A" factory-method="getB" factory-bean="a"></bean>

Example of the Static Factory Method of the First Type:

So far, you should understand from above that the object type returned from calling the static factory method may be the same class or entirely another class. In this example, we will use the first case where class A creates its own instance calling a Static factory method. For this purpose, we have created three files here:

  • A.java
  • applicationContext.xml
  • Test.java

A.java

This is a Singleton class with the following code:

package com.intellinuts;  
public class A {  
private static final A obj=new A();  
private A(){System.out.println("private constructor");}  
public static A getA(){  
    System.out.println("factory method ");  
    return obj;  
}  
public void msg(){  
    System.out.println("hello user");  
}  
}  

Here class A just returns its own instance by calling the get() static factory method.

applicationContext.xml

The XML configuration file of this type of static factory method is:

<?xml version="1.0" encoding="UTF-8"?>  
<beans  
    xmlns="http://www.springframework.org/schema/beans"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xmlns:p="http://www.springframework.org/schema/p"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans   
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">  
<bean id="a" class="com.intellinuts.A" factory-method="getA"></bean>  
</beans>

Test.java

The Test class will get the bean from the applicationContext.xml file and call the msg() method to display the output.

package org.sssit;  
import org.springframework.context.ApplicationContext;  
import org.springframework.context.support.ClassPathXmlApplicationContext;  
public class Test {  
public static void main(String[] args) {  
    ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");  
    A a=(A)context.getBean("a");  
    a.msg();  
}  
}  

The above program will display the output as:

private constructor
factory method
hello user

Example of the Static Factory Method of the Second Type:

We will use a simple code to inject the dependency by a static factory method that returns an instance of another class. For this purpose, we have created six files that are;

  • Printable.java
  • A.java
  • B.java
  • PrintableFactory.java
  • applicationContext.xml
  • Test.java

Printable.java

First, we create the class Printable. The class is instantiated by other classes.

package com.intellinuts;  
public interface Printable {  
void print();  
}  

A.java

Now, we will create the class named A, which implements class Printable.

package com.intellinuts;  
public class A implements Printable{  
    @Override  
    public void print() {  
        System.out.println("hello a");  
    }  

}  

B.java

Class B also implements the Class Printable.

package com.intellinuts;  
public class B implements Printable{  
    @Override  
    public void print() {  
        System.out.println("hello b");  
    }  
}  

PrintableFactory.java

The class PrintableFactory.java will get and return the instance of either class A or Class B by calling the getPrintable() method.

package com.intellinuts;  
public class PrintableFactory {  
public static Printable getPrintable(){  
    //return new B();  
          return new A();//return any one instance, either A or B  
}  
} 

applicationContext.xml

The XML configuration file will be as follows:

<?xml version="1.0" encoding="UTF-8"?>  
<beans  
    xmlns="http://www.springframework.org/schema/beans"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xmlns:p="http://www.springframework.org/schema/p"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans   
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">  
<bean id="p" class="com.intellinuts.PrintableFactory" factory-method="getPrintable"></bean>  
</beans>

Test.java

This class gets the bean from the applicationContext.xml file and calls the print() method to display the property of either class A or B.

package org.sssit;  
import org.springframework.context.ApplicationContext;  
import org.springframework.context.support.ClassPathXmlApplicationContext;  
public class Test {  
public static void main(String[] args) {  
    ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");  
    Printable p=(Printable)context.getBean("p");  
    p.print();  
}  
} 

The output will be displayed as hello a

Example of the Non-Static Factory Method

A Non-Static factory method is one that is called ON an instance of another class. This type of method can only be called from a static method to have an instance of the class including the non-static method. A Non-static method enables you to access any static method and static variable, without the creation of an instance of the object.

In this example, we will inject the dependency by a non-static factory method that returns an instance of another class. To achieve this, we will create six files below:

  • Printable.java
  • A.java
  • B.java
  • PrintableFactory.java
  • applicationContext.xml
  • Test.java

In this example, out of six files that we have mentioned in the previous examples, only two files need to be changed that are PrintableFactory and applicationContext.xml., the others will remain the same.

PrintableFactory.java

package com.intellinuts;  
public class PrintableFactory {  
//non-static factory method  
public Printable getPrintable(){  
    return new A();//return any one instance, either A or B  
}  
} 

In the above code, Class PrintableFactory uses printable (non-static factory method) to get the instance of other classes.

applicationContext.xml

 <?xml version="1.0" encoding="UTF-8"?>  
<beans  
    xmlns="http://www.springframework.org/schema/beans"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xmlns:p="http://www.springframework.org/schema/p"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans   
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">  
<bean id="p" class="com.intellinuts.PrintableFactory" factory-method="getPrintable"></bean>  
</beans> 

In the configuration file, in the bean tag, factory-method is used as the non-static method to get the bean values.

Here is the output of the above program: hello a