Spring FactoryBean Example

Spring FactoryBean is a special beans in spring framework. It can be used as a bean factory to create other Spring managed beans. You may be already familiar with built-in FactoryBean such as JndiObjectFactoryBean which is used to lookup jndi object, LocalSessionFactoryBean which is used to create hibernate session object, but this article will tell you how to create your own FactoryBean with examples.

How to create FactoryBean.

  1. Implement org.springframework.beans.factory.FactoryBean Interface.
    If your java class implement this interface, you must override below methods.
    getObjectType() : Return the class of the returned bean object.
    isSingleton() : true means the returned bean is a singleton type, otherwise return prototype type.
    getObject() : Return the instance of the factory generated bean class.
  2. Extends abstract class org.springframework.beans.factory.config.AbstractFactoryBean. If you extends this abstract class, you just need to override below two methods.
    getObjectType() : Return the class of the returned bean object.
    createInstance() : Return the instance of the factory generated bean class.

Customize FactoryBean Example

This example will create a factorybean which can generate java.sql.Connection object by the database type. It will implement interface org.springframework.beans.factory.FactoryBean.

DBConnectionFactoryBean.java

public class DBConnectionFactoryBean implements FactoryBean {
	
	private String jdbcDriverClass;
	
	private String connectionUrl;
	
	private String dbUserName;
	
	private String dbPassword;

	public String getJdbcDriverClass() {
		return jdbcDriverClass;
	}

	public void setJdbcDriverClass(String jdbcDriverClass) {
		this.jdbcDriverClass = jdbcDriverClass;
	}

	public String getConnectionUrl() {
		return connectionUrl;
	}

	public void setConnectionUrl(String connectionUrl) {
		this.connectionUrl = connectionUrl;
	}

	public String getDbUserName() {
		return dbUserName;
	}

	public void setDbUserName(String dbUserName) {
		this.dbUserName = dbUserName;
	}

	public String getDbPassword() {
		return dbPassword;
	}

	public void setDbPassword(String dbPassword) {
		this.dbPassword = dbPassword;
	}

        // Return factory generated bean object class.
	@Override
	public Class<?> getObjectType() {
		return Connection.class;
	}
        
        // Return database Connection object with provided database jdbc parameters.
	@Override
	public Connection getObject() throws Exception {
		
		/* Register jdbc driver class. */
		Class.forName(this.getJdbcDriverClass());
		
		/* Get the jdbc Connection object. */
		Connection ret = DriverManager.getConnection(this.getConnectionUrl(), this.getDbUserName() , this.getDbPassword());
		
		return ret;
	}

        // Whether the generated bean is singleton or not.
	@Override
	public boolean isSingleton() {
		return true;
	}
	
	// Test this factory bean.
	public static void main(String args[])
	{
		try
		{
		   	// Initiate Spring application context, this line code will invoke bean initialize method.
			ApplicationContext springAppContext = new ClassPathXmlApplicationContext("BeanSettings.xml");
	
			// Get mysql connection object. 
			Connection mysqlConn = (Connection) springAppContext.getBean("mysqlDBConnection");
			String mysqldbProductName = mysqlConn.getMetaData().getDatabaseProductName();
			String mysqldbProductVersion = mysqlConn.getMetaData().getDatabaseProductVersion();
			System.out.println("mysqldbProductName = " + mysqldbProductName + " , mysqldbProductVersion = " + mysqldbProductVersion);
			System.out.println("");
			
			// Get oracle connection object. 
			Connection oracleConn = (Connection) springAppContext.getBean("oracleDBConnection");
			String oracledbProductName = oracleConn.getMetaData().getDatabaseProductName();
			String oracledbProductVersion = oracleConn.getMetaData().getDatabaseProductVersion();
			System.out.println("oracledbProductName = " + oracledbProductName + " , oracledbProductVersion = " + oracledbProductVersion);
			System.out.println("");
	
			// Get SqlServer connection object. 
			Connection sqlServerConn = (Connection) springAppContext.getBean("sqlServerDBConnection");
			String sqlServerdbProductName = sqlServerConn.getMetaData().getDatabaseProductName();
			String sqlServerdbProductVersion = sqlServerConn.getMetaData().getDatabaseProductVersion();
			System.out.println("sqlServerdbProductName = " + sqlServerdbProductName + " , sqlServerdbProductVersion = " + sqlServerdbProductVersion);
			System.out.println("");
			
			// Get postgresql connection object. 
			Connection postgresqlConn = (Connection) springAppContext.getBean("postgresqlDBConnection");
			String postgresqldbProductName = postgresqlConn.getMetaData().getDatabaseProductName();
			String postgresqldbProductVersion = postgresqlConn.getMetaData().getDatabaseProductVersion();
			System.out.println("postgresqldbProductName = " + postgresqldbProductName + " , postgresqldbProductVersion = " + postgresqldbProductVersion);
			System.out.println("");
		}catch(Exception ex)
		{
			ex.printStackTrace();
		}

	}
}

BeanSettings.xml

This spring application configuration xml file will config four database connection factorybean, and each will return a java.sql.Connection object connected to related database for example oracle, mysql, sql server and postgresql.

 <bean id="oracleDBConnection" class="com.dev2qa.example.spring.bean.factorybean.DBConnectionFactoryBean"> 
     <property name="jdbcDriverClass" value="oracle.jdbc.driver.OracleDriver"> </property> 
     <property name="connectionUrl" value="jdbc:oracle:thin:@localhost:1521:DataTiger"> </property> 
     <property name="dbUserName" value="system"> </property> 
     <property name="dbPassword" value="manager"> </property> 
</bean> 

<bean id="mysqlDBConnection" class="com.dev2qa.example.spring.bean.factorybean.DBConnectionFactoryBean"> 
     <property name="jdbcDriverClass" value="com.mysql.jdbc.Driver"> </property> 
     <property name="connectionUrl" value="jdbc:mysql://localhost:3306/test"> </property> 
     <property name="dbUserName" value="root"> </property> 
     <property name="dbPassword" value=""> </property> 
</bean> 

<bean id="sqlServerDBConnection" class="com.dev2qa.example.spring.bean.factorybean.DBConnectionFactoryBean"> 
     <property name="jdbcDriverClass" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"> </property> 
     <property name="connectionUrl" value="jdbc:sqlserver://localhost:1433;databaseName=TestDB;user=sa;password=sa"> </property> 
     <property name="dbUserName" value="sa"> </property> 
     <property name="dbPassword" value="sa"> </property> 
</bean> 

<bean id="postgresqlDBConnection" class="com.dev2qa.example.spring.bean.factorybean.DBConnectionFactoryBean"> 
     <property name="jdbcDriverClass" value="org.postgresql.Driver"> </property> 
     <property name="connectionUrl" value="jdbc:postgresql://localhost:5432/student"> </property> 
     <property name="dbUserName" value="postgres"> </property> 
     <property name="dbPassword" value="postgres"> </property> 
</bean>

If you install database and add related jdbc jar file into your java project, run above example, you can get below output.

READ :   Spring Component Scan Instruction

database connection factorybean output

If you want to get the FactoryBean instance it self, you can add “&” charactor before the spring manged bean id when get it as below java code.

	// Get the factorybean itself.
	DBConnectionFactoryBean dbConnFB = (DBConnectionFactoryBean)springAppContext.getBean("&mysqlDBConnection");
	System.out.println("JDBC driver class : " + dbConnFB.getJdbcDriverClass());
	System.out.println("JDBC connection url : " + dbConnFB.getConnectionUrl());
	System.out.println("DB username : " + dbConnFB.getDbUserName());
	System.out.println("DB password : " + dbConnFB.getDbPassword());
	System.out.println("");

Download “Spring-FactoryBean-Example.zip” Spring-FactoryBean-Example.zip – Downloaded 58 times – 3 KB

(Visited 963 times, 1 visits today)

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.