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(); } }
There are three types of Factory methods which are described below:
<bean id="a" class="com.intellinuts.A" factory-method="getA"></bean>
<bean id="b" class="com.intellinuts.A" factory-method="getB"></bean>
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>
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:
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.
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>
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
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;
First, we create the class Printable. The class is instantiated by other classes.
package com.intellinuts; public interface Printable { void print(); }
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"); } }
Class B also implements the Class Printable.
package com.intellinuts; public class B implements Printable{ @Override public void print() { System.out.println("hello b"); } }
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 } }
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>
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
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:
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.
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.
<?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