2017-05-25 90 views
0

我正在为我的log4j输出使用JDBC连接器,并且想将我的日志条目发布到Postgres数据库。这看起来如下:带参数的工厂模式

<Jdbc name="Jdbc" tableName="log"> 
    <ConnectionFactory class="database.ConnectionFactory" method="getConnection"/> 
    <Column name="event_date" isEventTimestamp="true" /> 
    <Column name="level" pattern="%level" isUnicode="false" /> 
    <Column name="logger" pattern="%logger" isUnicode="false" /> 
    <Column name="message" pattern="%message" isUnicode="false" /> 
    <Column name="exception" pattern="%ex{full}" isUnicode="false" /> 
</Jdbc> 

据我理解这一点需要与方法getConnection静态类,我实现了这个使用工厂模式:

public class ConnectionFactory { 
    private static interface Singleton { 
     final ConnectionFactory INSTANCE = new ConnectionFactory(); 
    } 

    private ComboPooledDataSource comboPooledDataSource; 

    private ConnectionFactory() { 
     comboPooledDataSource = new ComboPooledDataSource(); 
     try { 
      // Load the jdbc driver. 
      comboPooledDataSource.setDriverClass("org.postgresql.Driver"); 
     } catch (PropertyVetoException exception) { 

     } 

     // Need to create datasource here, requires parameters. 
    } 

    public static Connection getConnection() throws SQLException { 
     return Singleton.INSTANCE.comboPooledDataSource.getConnection(); 
    } 
} 

我的问题是,我想通过参数(主机,端口,数据库等)创建与数据库的连接,并且不想对其进行硬编码。另外,拥有一个静态类来保存配置并不是首选,因为我希望能够轻松进行单元测试。

什么是实现此目标的好方法?我是否可以忽视某些事情,或者这是一种不好的做法?

回答

0

工厂方法可以带参数。

+0

谢谢您的回答。虽然这通常是真实的,但在这种情况下,我将有一个连接池,我不想每次调用getConnection()都重新创建连接池,因为这会打破整个池的概念。所以我不认为我应该传递参数来创建连接池到这个方法中。 – Freddy

0

使用反射和枚举可以帮助: 我已经实现了这样的事情我自己:

public class BusFactory { 

public IBus createBus(BusType busType, String busUrl) { 

    try { 

     if(busType == null){ 
      return null; 
     } 

     //Touraj: Get Bus By Reflection 

     Class<?> busClass = Class.forName(busType.getFullQualifiedName()); 
     Constructor con = busClass.getConstructor(String.class); 

     Object busObj = con.newInstance(busUrl); 

     if (busObj instanceof ETCDBus) { 

      return (ETCDBus)busObj; 

     } else if (busObj instanceof AeroSpikeBus) { 

      return (AeroSpikeBus)busObj; 

     }else 
     { 
      throw new UnsupportedBusException("this Type of Bus is not Supported"); 
     } 

    } catch (ClassNotFoundException e) { 
     e.printStackTrace(); 
    } catch (InstantiationException e) { 
     e.printStackTrace(); 
    } catch (IllegalAccessException e) { 
     e.printStackTrace(); 
    } catch (NoSuchMethodException e) { 
     e.printStackTrace(); 
    } catch (InvocationTargetException e) { 
     e.printStackTrace(); 
    } catch (UnsupportedBusException e) { 
     e.printStackTrace(); 
    } 

    return null; 
} 
} 

和BusType是这样的:

public enum BusType { 

ETCD("BUS.ETCDBus"), 
AEROSPIKE("AEROSPIKE"), 
RAIMA("RAIMA"), 
HANA("HANA"), 
GEODE("GEODE"), 
IGNITE("IGNITE"), 
SENTINEL("SENTINEL"), 
REDIS("BUS.RedisBus"), 
Informix("Informix"); 

private String fullQualifiedName; 

BusType(String fullQualifiedName) { 
    this.fullQualifiedName = fullQualifiedName; 
} 

public String getFullQualifiedName() { 
    return fullQualifiedName; 
} 

}