Spring – Dependency Injection with Factory Method

Spring framework provides Dependency Injection to remove the conventional dependency relationship between objects. To inject dependencies using the factory method, we will use two attributes factory-method and factory-bean of bean elements.

Note: Factory methods are those methods that return the instance of the class.

  • Factory Method: These are those types of methods that are invoked to inject the beans.
  • Factory Bean: These are the references of the beans by which factory methods are invoked.

Types of Factory Method

There are three types of factory methods:

  1. Static Factory Method – It is used to return the instance of its own class. Static factory methods are commonly used for Singleton Design Pattern.
  2. Static Factory Method – It is used to return the runtime instance of another class.
  3. Non-Static Factory Method – It is used to return the runtime instance of another class through an instance method, allowing for more flexible and customizable instantiation processes.

Implementation of Spring Dependency Injection with Factory Method

Here, we will be injecting the dependencies using a factory pattern. For this, we will create a class and name it Beginner.java and inject this class as the dependency.

A. Static Factory Method – A returning instance of own class

In this example, we will create a singleton class Beginner.java and inject its dependency in our main class using the factory method.

Step 1: Create Beginner Class

For this create a Beginner.java. We will also define a BeginnerMessage() method to test the dependency injection using the factory method. Below is the code for Beginner.java class.

File: Beginner.java:

Java
// Java Program to Illustrate Beginner Class 

// Class 
public class Beginner {

    // define a private static instance
    public static final Beginner Beginner = new Beginner();
    
    // private constructor
    private Beginner() {}
    
    // this method will return the above instance
    // which was created when the class loaded in the memory
    public static Beginner getBeginner() {
        return Beginner;
    }
    
    // this method is used to check the dependency injection
    public void BeginnerMessage() {
        System.out.println("Welcome to w3wiki. DI for static factory method working good");
    }
}


Step 2: Adding Dependencies

In this step, we will add the following dependencies in pom.xml file.

pom.xml:

XML
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.w3wiki</groupId>
  <artifactId>DIFactoryMethods</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  
  <dependencies>
  <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
    <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.8.RELEASE</version>
    </dependency>
   </dependencies>
</project>

 
 

Step 3: Bean Configuration

Now, we will create application-context.xml file in our class path. We will use the application-context file to configure our bean using factory method. Below is the code for the application-context.xml file.

application-context.xml:

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">  
 
 <!-- Note: You need to define your whole class path for your Beginner.java class -->
  
    <bean id="BeginnerId" class="com.w3wiki.model.Beginner"
        factory-method="getBeginner">
    </bean>
  
</beans>

 
Step 4: Create Utility Class

Now, we will create a Utility class for testing our application. For this create a new class and name it TestDIFactoryMethod.java and add the following code to it.

TestDIFactoryMethod.java:

Java
// Java Program to Illustrate TestDIFactoryMethod Class

// Importing required classes
import com.w3wiki.model.Beginner;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

// Class
public class TestDIFactoryMethod {

    // Main driver method
    public static void main(String[] args)
    {

        // Reading the application-context file
        // from the class-path
        AbstractApplicationContext context
            = new ClassPathXmlApplicationContext(
                "application-context.xml");

        // Spring check the blueprint for Beginner bean
        // from application-context.xml file and return it
        Beginner BeginnerObj = (Beginner)context.getBean("BeginnerId");

        // BeginnerObj contain the dependency of Beginner class
        BeginnerObj.BeginnerMessage();
    }
}

 
Step 5: Run the application

Now, we will run the application, and the output will be like below:

Output:

B. Static Factory Method – Returning Instance of Another Class

In this example, we will inject dependencies of other classes using the static factory method.

Step 1: Create An Interface

We will create an interface and name it BeginnerCourses.java and define a getCourseDetail() method in it.

BeginnerCourses.java:

Java
// Java Program to Illustrate BeginnerCourses interface

// Interface
public interface BeginnerCourses {

    // Print statement
    public void getCourseDetail();
}

 
 Step 2: Create Dependent Classes

In this step, we will create two different classes DSACourses and JavaCourses. We will implement the BeginnerCourses interface from these class and override the getCourseDetail() method. Below is the code for both the classes.

DSACourses.java:

Java
// Java Program to Illustrate DSACourses Class

// Class
// Implementing BeginnerCourses interface
public class DSACourses implements BeginnerCourses {

    // Method
    // Override the getCourseDeail()
    public void getCourseDetail()
    {
        // Print statement
        System.out.println("Data Structure & Algorithms");
    }


JavaCourses.java:

Java
// Java Program to Illustrate JavaCourses Class

// Class
// Implementing BeginnerCources interface
public class JavaCourses implements BeginnerCourses {

    // Method
    // Override the getCourseDeail()
    public void getCourseDetail()
    {
        // Print statement
        System.out.println("Core Java Collections");
    }
}

 
Step 3: Create A Factory Class

Now, we will create a CourseFactory class. This class will have a static factory method for the BeginnerCourses interface which will return the instance of another class (DSACourses and JavaCourses). Below is the code for CourseFactory.java class.

CourseFactory.java:

Java
// Java Program to Illustrate CourseFactory Class

package com.w3wiki.model;

// Importing required classes
import com.w3wiki.dao.BeginnerCourses;
import com.w3wiki.dao.JavaCourses;

// Class
public class CourseFactory {

    // Method
    // factory method returning instance to another class
    public static BeginnerCourses getCourses()
    {
        // Returning the instance of JavaCourses class
        // One can also return the instance of DSACourses
        return new JavaCourses();
    }
}

 
Step 4: Bean Configuration

Now, we will create application-context.xml file in our classpath. We will use the application-context file to configure our bean using the factory method.

application-context.xml:

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">  
 
 <!-- Note: You need to define your whole class path for your CourseFactory.java class -->
  
    <bean id="courseId" class="com.w3wiki.model.CourseFactory"
        factory-method="getCourses">
    </bean>
  
</beans>

 
Step 5: Create Utility Class

Now, we will create a Utility class for testing our application. For this create a new class and name it TestDIFactoryMethod.java and add the following code to it.

TestDIFactoryMethod.java:

Java
// Java Program to Illustrate TestDIFactoryMethod Class

// importing required classes
import com.w3wiki.dao.BeginnerCourses;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

// Class
public class TestDIFactoryMethod {

    // Main driver method
    public static void main(String[] args)
    {

        // Reading the application-context file
        // from the class-path
        AbstractApplicationContext context
            = new ClassPathXmlApplicationContext(
                "application-context.xml");

        // Spring check the blueprint for BeginnerCourses bean
        // from application-context.xml file and return it
        BeginnerCourses BeginnerCourses
            = (BeginnerCourses)context.getBean("courseId");

        // BeginnerCourses contain the dependency
        // of BeginnerCourses class
        BeginnerCourses.getCourseDetail();
    }
}

 
Step 6: Run the application

Now, we will run this application, and the output will be like below: 

Output:
 

C. Non-Static Factory Method – Returning instance of another class

In this example, we will inject dependencies of other classes using the non-static factory method.

Step 1: Create An Interface

We will create an interface and name it BeginnerCourses.java and define a getCourseDetail() method in it.

BeginnerCourses.java:

Java
// Java Program to Illustrate BeginnerCourses Interface 

// Interface
public interface BeginnerCourses 
{
    // Print statement 
    public void getCourseDetail();
}

 
Step 2: Create Dependent Classes

In this step, we will create two different classes DSACourses and JavaCourses. We will implement the BeginnerCourses interface from these classes and override the getCourseDetail() method. Below is the code for both classes.

DSACourses.java:

Java
// Java Program to illustrate DSACourses Class

// Class
// Implementing BeginnerCourses interface
public class DSACourses implements BeginnerCourses {

    // Override the getCourseDeail() method
    public void getCourseDetail()
    {
        // Print statement
        System.out.println("Data Structure & Algorithms");
    }
}

 

JavaCourses.java:

Java
// Java Program to Illustrate JavaCourses Class

// Class
public class JavaCourses implements BeginnerCourses {

    // Method
    // Override the getCourseDeail() method
    public void getCourseDetail()
    {
        // Print statement
        System.out.println("Core Java Collections");
    }
}

 
Step 3: Create A Factory Class

Now, we will create a CourseFactory class. This class will have a non-static factory method for the BeginnerCourses interface which will return the instance of another class (DSACourses and JavaCourses).

CourseFactory.java:

Java
// Java Program to Illustrate CourseFactory Class  

// Importing required classes
import com.w3wiki.dao.DSACourses;
import com.w3wiki.dao.BeginnerCourses;

// Class
public class CourseFactory {

    // Non-static factory method that returns
    // the instance to another class
    public BeginnerCourses getCourses()
    {

        // Returning the instance of JavaCourses class
        // One can also return the instance of DSACourses
        return new DSACourses();
    }
}

 
Step 4: Bean Configuration

Now, we will create an application-context.xml file in our class-path. We will use application-context file to configure our bean using factory method.

application-context.xml:

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">  
 
 <!-- Note: You need to define your whole class path for your CourseFactory.java class -->
  
   <bean id="courseFactory" class="com.w3wiki.model.CourseFactory"></bean>  
    <bean id="courseId" class="com.w3wiki.model.CourseFactory"
        factory-method="getCourses" factory-bean="courseFactory">
    </bean>
  
</beans>

 
Step 5: Create Utility Class

Now, we will create a Utility class for testing our application. For this create a new class and name it TestDIFactoryMethod.java and add the following code to it.

TestDIFactoryMethod.java:

Java
// Java Program to Illustrate TestDIFactoryMethod Class

// Importing required classes
import com.w3wiki.dao.BeginnerCourses;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

// Class
public class TestDIFactoryMethod {

    // Main driver method
    public static void main(String[] args)
    {

        // Reading the application-context file
        // from the class-path
        AbstractApplicationContext context
            = new ClassPathXmlApplicationContext(
                "application-context.xml");

        // Spring check the blueprint for BeginnerCourses bean
        // from application-context.xml file and return it
        BeginnerCourses BeginnerCourses
            = (BeginnerCourses)context.getBean("courseId");

        // BeginnerCourses contain the dependency
        // of BeginnerCourses class
        BeginnerCourses.getCourseDetail();
    }
}

 
Step 6: Run the application

Now, we will run this application, and the console output will be like below.

Output: