Spring FactoryBean Example

Spring FactoryBean is a special bean in the 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 objects, but this article will tell you how to create your own FactoryBean with examples.

1. How to create FactoryBean.

  1. Implement org.springframework.beans.factory.FactoryBean Interface. If your java class implements this interface, you must override the 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 extend this abstract class, you just need to override the below two methods.
    getObjectType(): Return the class of the returned bean object.
    createInstance(): Return the instance of the factory-generated bean class.

2. Customize FactoryBean Example.

  1. This example will create a FactoryBean that can generate java.sql.Connection object by the database type.
  2. It will implement the interface org.springframework.beans.factory.FactoryBean.
  3. 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();
    		}
    
    	}
    }
  4. BeanSettings.xml. This spring application configuration XML file will config four database connection FactoryBeans, and each will return a java.sql.Connection object connected to the 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>
  5. If you install a database and add the related JDBC jar file into your java project, run the above example, you can get the below output.
    mysqldbProduceName = MySQL , mysqldbProductVersion= 5.5.5-10.1.24-MariaDB
    
    sqlServerdbProduceName = Microsoft SQL Server, sqlServerdbProductVersion= 11.00.2100
    
    postgresqldbProduceName = PostgreSQL , postgresqldbProductVersion= 9.6.4
  6. If you want to get the FactoryBean instance itself, you can add the “&” character before the spring managed bean id when getting it, below is the example 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("");
    

Leave a Comment

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.