Spring — Static Factories | Code Factory

Code Factory
4 min readJan 22, 2021

--

Donate : Link

WordPress Blog : Link

Applications… : Link

Spring Tutorial Index Page: Link

  • In Singleton we declare constructor as private and we have only single object through out the application but as you know if we have private constructor then still Spring will create object. Example: In Test class we define property of Calendar and in xml we declare bean for Test class and also for Calendar also. In this scenario it will create object for Calendar and then assign it to Test class.
  • Calender is singleton class so we normally create object using Calendar.getInstance(). Internally it will do some calculation and then return object. But if we create object through container then it is not good practise.
<bean id="c" class="java.util.Calendar" /> // don't create object of singleton like this
  • To create object using factory method like Calendar.getInstance() then we have to use factory-method attribute in <bean> tag.
<bean id="c" class="java.util.Calendar" factory-method="getInstance" />
  • * We create Logger object using LoggerFactory.getLogger(this.class), we create Validator object in Hibernate using ValidatorFactory.getValidator(), we create Session object in Hibernate using sessionFactory.openSession(). Notice here that in Logger and Validator we create object using static method but in Session we create or get object using sessionFactory object so openSession() is a instance/non-static method. We create object of that using below code.
<bean id="lf" class="LoggerFactory" factory-method="getLogger" />
<bean id="sf" class="SessionFactory" />
<bean id="s" factory-bean="sf" factory-method="openSession" />
Logger l = getBean("lf");
Session s = getBean("s");

Create Java Project

  • Open Eclipse
  • Go to File -> New -> Others… -> Java Project
  • Create FactoryMethods project
  • Right click on project -> Build Path -> Configure Build Path -> Libraries tab -> Add External JARs
    - commons-logging-X.X.jar
    - spring-beans-X.X.X.jar
    - spring-context-X.X.X.jar
    - spring-core-X.X.X.jar
  • * You can find dtd information from spring-beans-X.X.X.jar -> org -> springframework -> beans -> factory -> xml -> spring-beans.dtd (line no 36 & 37)

spring.xml

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<bean id="t" class="com.codeFactory.beans.Test" factory-method="getInstance" />
<bean id="c" class="java.util.Calendar" factory-method="getInstance" />
</beans>

Test.java

package com.codeFactory.beans;/**
* @author code.factory
*
*/
public class Test {
private static Test t;

private Test() {
System.out.println("Private constructor.");
}

public static Test getInstance() {
if(t == null) {
t = new Test();
}
return t;
}

@Override
protected Object clone() throws CloneNotSupportedException {
return new CloneNotSupportedException();
}
}

Client.java

package com.codeFactory.beans;/**
* @author code.factory
*
*/
public class Test {
private static Test t;

private Test() {
System.out.println("Private constructor.");
}

public static Test getInstance() {
if(t == null) {
t = new Test();
}
return t;
}

@Override
protected Object clone() throws CloneNotSupportedException {
return new CloneNotSupportedException();
}
}

Output:

Private constructor.
true
true

Create Java Project

  • Open Eclipse
  • Go to File -> New -> Others… -> Java Project
  • Create FactoryClasseInstanceMethod project
  • Right click on project -> Build Path -> Configure Build Path -> Libraries tab -> Add External JARs
    - commons-logging-X.X.jar
    - spring-beans-X.X.X.jar
    - spring-context-X.X.X.jar
    - spring-core-X.X.X.jar
  • * You can find dtd information from spring-beans-X.X.X.jar -> org -> springframework -> beans -> factory -> xml -> spring-beans.dtd (line no 36 & 37)

spring.xml

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<bean id="cf" class="com.codeFactory.beans.CarFactory" >
<property name="companyName" value="com.codeFactory.beans.JLR" />
</bean>

<bean id="c" factory-bean="cf" factory-method="getInstance" />
</beans>

Car.java

package com.codeFactory.beans;/**
* @author code.factory
*
*/
public interface Car {
public void drive();
}

CarFactory.java

package com.codeFactory.beans;/**
* @author code.factory
*
*/
public class CarFactory {
public String companyName;
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
/* instance / non-static factory */
public Car getInstance() throws Exception {
return (Car) Class.forName(companyName).newInstance();
}
}

Audi.java

package com.codeFactory.beans;/**
* @author code.factory
*
*/
public class Audi implements Car {
@Override
public void drive() {
System.out.println("Maximum speed is 200");
}
}

JLR.java

package com.codeFactory.beans;/**
* @author code.factory
*
*/
public class JLR implements Car {
@Override
public void drive() {
System.out.println("Maximum speed is 250");
}
}

Client.java

package com.codeFactory.test;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.codeFactory.beans.Car;/**
* @author code.factory
*
*/
public class Client {
public static void main(String... args) {
ApplicationContext context = new ClassPathXmlApplicationContext("com/codeFactory/resources/spring.xml");

Car c = (Car) context.getBean("c");
c.drive();
}
}

Output:

Maximum speed is 250

--

--