APACHE LOG4J™ 2 学习笔记-log4j2 环境部署到各种类型输出+maven\mysql\滚动文件\控制台\异步\过滤器
来源:互联网 发布:北交大知行平台注册 编辑:程序博客网 时间:2024/06/06 02:53
前言
本文将展示在maven/spring+hibernate环境中实现log4j2日志的输出,包括分级输出到控制台、日志(按日志文件大小、日期分割、限定文件个数)、数据库。
Log4j2可以实现对log4j、slf4j、java自带日志的兼容。
Log4j2的官方文档地址如下
http://logging.apache.org/log4j/2.x/manual/appenders.html#FailoverAppender
开始实施
1、maven的pom.xml配置Log4j2的依赖
<!-- 日志框架声明:http://blog.csdn.net/edward0830ly/article/details/8250412 http://blog.csdn.net/ziruobing/article/details/3919501 http://blog.csdn.net/autfish/article/details/51203709--><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.7</version></dependency><dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.7</version></dependency><!-- log4j2-链接数据库 --><dependency> <groupId>commons-pool</groupId> <artifactId>commons-pool</artifactId> <version>1.6</version></dependency>
2、创建log4j2.xml
3、编写log4j2.xml的一般形式
在log4j2.xml文件中我们需要做出这样一些配置。
·日志的名字是什么,比如root日志是根日志,可以在调用的时候直接声明调用根日志,也可以任意命名一个日志去调用,当然,跟日志也可以引用自定义日志。
·日志的级别是什么,比如是info或者warn,也可以使用过滤器,让不同的级别的日志输出到不同的日志中去。
·日志输出到什么地方,比如是控制台,日志文件或者是数据库。
·同步输出日志还是异步输出日志。
·输出日志的格式,比如仅仅显示日期和信息还是类名和方法名等。
·在配置文件中配置常量。
·高级用法,以及以json格式描述的log4j.xml(本文不涉及,更多介绍请参考官方文档)
4、将日志以某种格式输出到控制台及测试方法
log4j2.xml内容,<Appenders>决定日志以哪种格式输出到什么地方,<Loggers>则约定了被具体代码应用的日志的名字,通过 <AppenderRef>和<Appenders>联系起来
<?xml version="1.0" encoding="UTF-8"?><Configuration status="WARN" monitorInterval="300"><!-- 每隔300秒重新读取配置文件,对web应用很实用 --> <Appenders> <!-- 日志输出格式 :<Console是控制台,<File是文件,<RollingRandomAccessFile按时间和文件大小生成多个日志,<JDBC是数据库,<Async异步--> <!-- Console 输出到控制台及格式--> <Console name="toConsole" target="SYSTEM_OUT"> <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %F %M %l- %-5level %logger{36} %msg%n" /> </Console> </Appenders> <Loggers><!-- 日志类别 --> <!-- 定义根日志类别 查看level http://blog.csdn.net/techq/article/details/6636287--> <Root level="trace"> <AppenderRef ref="toConsole" /> </Root> <!-- 输出到控制台 --> <Logger name="mylog" additivity="false" level="TRACE"><!--additivity="false" 不再输出父级日志 --> <AppenderRef ref="toConsole" /> </Logger> </Loggers> </Configuration>
测试方法-根日志输出到控制台
/** * 测试root日志打印到控制台 */@Testpublic void testLog4j2(){Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME); logger.trace("trace level"); logger.debug("debug level"); logger.info("info level"); logger.warn("warn level"); logger.error("error level"); logger.fatal("fatal level"); }测试方法-name为“mylog”的Logger输出到控制台-additivity=“false”则跟日志不再输出,否则根日志默认会再次输出一次
/** * 测试自定义日志打印到控制台 */@Testpublic void testLog4j2SC(){ Logger logger = LogManager.getLogger("mylog"); logger.trace("trace level"); logger.debug("debug level"); logger.info("info level"); logger.warn("warn level"); logger.error("error level"); logger.fatal("fatal level");}
日志格式和输出内容比对如下
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %F %M %l- %-5level %logger{36} %msg%n" />
2017-01-16 22:20:11.224 [main] TestForAll.java testLog4j2 com.bestcxx.mavenstu.mavenssh.util.TestForAll.testLog4j2(TestForAll.java:14)- TRACE trace level
5、将日志输出到文件
输出到文件有2种应用模式,1是直接输出到一个文件,2是限定日志文件大小、名字和总数来滚动输出,第2种也是使用较为广泛的
·直接输出到一个文件
log4j2.xml内容
<?xml version="1.0" encoding="UTF-8"?><Configuration status="WARN" monitorInterval="300"><!-- 每隔300秒重新读取配置文件,对web应用很实用 --> <Appenders> <!-- 日志输出格式 :<Console是控制台,<File是文件,<RollingRandomAccessFile按时间和文件大小生成多个日志,<JDBC是数据库,<Async异步--> <!-- File 输出到文件及格式 --> <File name="toFile" fileName="D://a/log/mavenssh.log"> <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" /> </File> </Appenders> <Loggers><!-- 日志类别 --> <!-- 定义根日志类别 查看level http://blog.csdn.net/techq/article/details/6636287--> <Root level="trace"> <AppenderRef ref="toFile" /> </Root> <!-- 输出到文件 --> <Logger name="mylogtofile" additivity="false" level="TRACE"><!--additivity="false" 不再输出父级日志 --> <AppenderRef ref="toFile" /> </Logger> </Loggers> </Configuration>
测试代码
/** * 自动以日志输出到文件 */@Testpublic void testLog4j2SF(){Logger logger = LogManager.getLogger("mylogtofile"); logger.trace("trace level"); logger.debug("debug level"); logger.info("info level"); logger.warn("warn level"); logger.error("error level"); logger.fatal("fatal level");}
·将日志按照一定的命名格式、限定日志大小和日志数量滚动输出到日志文件中
log4j2.xml内容,这里我们增加了常量,而且在调用测试的代码中,使用的不是root或者logger名字,而是类名.class,你会发现系统会在找不到对应的Logger时自动使用
Root这个日志配置
<?xml version="1.0" encoding="UTF-8"?><Configuration status="WARN" monitorInterval="300"><!-- 每隔300秒重新读取配置文件,对web应用很实用 --> <properties><!-- 定义常量 --> <property name="LOG_HOME">D://a/log</property> <property name="FILE_NAME">mavenssh2</property> </properties> <Appenders> <!-- 日志输出格式 :<Console是控制台,<File是文件,<RollingRandomAccessFile按时间和文件大小生成多个日志,<JDBC是数据库,<Async异步--> <!-- RollingRandomAccessFile TimeBasedTriggeringPolicy interval="1"一个最小时间单位生成一个文件 SizeBasedTriggeringPolicy size="1 MB" 当文件大小超过1MB生成一个日志文件,你可以写成0.001MB实验一下效果 DefaultRolloverStrategy max="2" 同一个时间节点最多生成2个日志文件,否则后面的覆盖前面的,如1分钟10MB,允许2个,则最终是第9MB和第10MB的日志存在 时间节点-index(1,2) --> <RollingRandomAccessFile name="toFileByRoll" fileName="${LOG_HOME}/${FILE_NAME}.log" filePattern="${LOG_HOME}/${date:yyyy-MM}/${FILE_NAME}-%d{yyyy-MM-dd HH-mm}-%i.log"> <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" /> <Policies> <TimeBasedTriggeringPolicy interval="1" /> <SizeBasedTriggeringPolicy size="0.001 MB" /> </Policies> <DefaultRolloverStrategy max="2" /> </RollingRandomAccessFile> </Appenders> <Loggers><!-- 日志类别 --> <!-- 定义根日志类别 查看level http://blog.csdn.net/techq/article/details/6636287--> <Root level="trace"> <AppenderRef ref="toFileByRoll" /> </Root> <!-- 按照时间节点和文件大小滚动生成日志 --> <Logger name="mylogtofileroll" additivity="false" level="TRACE"><!--additivity="false" 不再输出父级日志 --> <AppenderRef ref="toFileByRoll" /> </Logger> </Loggers> </Configuration>
测试代码
/** * 自动以日志输出到文件 * 滚动输出 */@Testpublic void testLog4j2SFR(){//Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);//根日志//Logger logger = LogManager.getLogger("mylogtofileroll");//自定义日志Logger logger = LogManager.getLogger(TestForAll.class);//以类名作为日志的名字 logger.trace("trace level"); logger.debug("debug level"); logger.info("info level"); logger.warn("warn level"); logger.error("error level"); logger.fatal("fatal level");}效果
和
6、以输出到控制台为例,编写异步日志(当然对于其他类型的日志也是一样的)
原理就是,如果有多个日志需要输出,则可以将这多个日志统一于<Appenders>下的<Async,然后被Root日志引用或者被自定义日志引用
例子为两个输出到控制台的格式定义被异步输出
<?xml version="1.0" encoding="UTF-8"?><Configuration status="WARN" monitorInterval="300"><!-- 每隔300秒重新读取配置文件,对web应用很实用 --> <Appenders> <!-- Console 输出到控制台及格式--> <Console name="toConsole" target="SYSTEM_OUT"> <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %F %M %l- %-5level %logger{36} %msg%n" /> </Console> <Console name="toConsole2" target="SYSTEM_OUT"> <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS}%msg[2]%n" /> </Console> <!-- 异步日志 --> <Async name="Async"> <AppenderRef ref="toConsole" /> <AppenderRef ref="toConsole2"/> </Async> </Appenders> <Loggers><!-- 日志类别 --> <!-- 定义根日志类别 查看level http://blog.csdn.net/techq/article/details/6636287--> <Root level="trace"> <AppenderRef ref="Async" /> </Root> <!-- 使用异步 --> <Logger name="asyncConsole" additivity="false" level="trace"> <AppenderRef ref="Async"/> </Logger> </Loggers> </Configuration>
测试代码
/** * 异步输出日志 * */@Testpublic void testLog4j2asyncConsole(){Logger logger = LogManager.getLogger("asyncConsole"); logger.trace("trace level"); logger.debug("debug level"); logger.info("info level"); logger.warn("warn level"); logger.error("error level"); logger.fatal("fatal level");}
效果
7、使用过滤器输出日志
好处是,将制定级别的日志保留到指定位置,而不是全部的
log4j2.xml内容
<?xml version="1.0" encoding="UTF-8"?><Configuration status="WARN" monitorInterval="300"><!-- 每隔300秒重新读取配置文件,对web应用很实用 --> <Appenders> <!-- Console 输出到控制台及格式-并使用过滤器 <Filters--> <Console name="toConsoleFilter" target="SYSTEM_OUT"> <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %F %M %l- %-5level %logger{36} %msg%n" /> <Filters> <ThresholdFilter level="fatal" onMatch="DENY" onMismatch="NEUTRAL" /><!-- 高级别优先设置,NEUTRAL不影响低等级设置 --> <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY" /> <!-- 低级别及以后遵循同样的标准-已经声明的高级别除外 --> </Filters> </Console> </Appenders> <Loggers><!-- 日志类别 --> <!-- 定义根日志类别 查看level http://blog.csdn.net/techq/article/details/6636287--> <Root level="trace"> <AppenderRef ref="toConsoleFilter" /> </Root> <!-- 使用过滤器 --> <Logger name="toConsoleFilter" level="trace" additivity="false"> <AppenderRef ref="toConsoleFilter" /> </Logger> </Loggers> </Configuration>
测试代码
/** * 自动以日志输出到控制台 * 过滤器 * 日志级别是 * trace->debug->info->warn->error->fatal * 本例中是 * 1、fatal 级别不输出 * 2、warn级别以及之后输出 * 综合是 warn之后以及fatal(不含fatal)级别之前输出 * */@Testpublic void testLog4j2ErrorNoFatal(){Logger logger = LogManager.getLogger("toConsoleFilter"); logger.trace("trace level"); logger.debug("debug level"); logger.info("info level"); logger.warn("warn level"); logger.error("error level"); logger.fatal("fatal level");}
效果是仅输出了warn和error级别的
8、在maven/ssh环境中将日志输出到数据库(这里是mysql,用到了数据库主键的自增)
首先,本文是在maven/ssh环境中运行的,所以需要在测试的时候需要加载配置文件的内容
需要读者具备ssh的基本知识,可以参考文章
http://blog.csdn.net/bestcxx/article/details/52975675
8.1 首先需要新建日志表
这里我使用的是自动建表,所以只新建了实体
package com.bestcxx.mavenstu.mavenssh.model;import java.io.Serializable;import java.util.Date;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.Table;import javax.persistence.Temporal;import javax.persistence.TemporalType;import org.hibernate.annotations.GenericGenerator;@SuppressWarnings("serial")@Table(name="LOGGER")@Entity(name="LOGGER")public class LoggerModel implements Serializable{private long eventId;//EVENT_ID 日志idprivate Date eventDate;//EVENT_DATE -注意这里必须使用sqlDateprivate String level;//LEVEL 日志的级别private String logger;//LOGGER 日志内容private String message;//MESSAGE 其他信息private String throwable;//THROWABLE 异常抛出@Id@GeneratedValue(strategy = GenerationType.AUTO)//主键自增-mysql//@GeneratedValue(strategy = GenerationType.IDENTITY)//@GenericGenerator(name = "persistenceGenerator", strategy = "increment") @Column(name="EVENT_ID",unique=true,nullable=false)public long getEventId() {return eventId;}public void setEventId(long eventId) {this.eventId = eventId;}@Column(name="EVENT_DATE")@Temporal(TemporalType.TIMESTAMP)public Date getEventDate() {return eventDate;}public void setEventDate(Date eventDate) {this.eventDate = eventDate;}@Column(name="LEVEL",nullable=false,length=10)public String getLevel() {return level;}public void setLevel(String level) {this.level = level;}@Column(name="LOGGER",nullable=true,length=100)public String getLogger() {return logger;}public void setLogger(String logger) {this.logger = logger;}@Column(name="MESSAGE",nullable=true,length=100)public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}@Column(name="THROWABLE",nullable=true,length=100)public String getThrowable() {return throwable;}public void setThrowable(String throwable) {this.throwable = throwable;}}
8.2 编写log4j2,xml调用的方法类
下面的方法是直接从官网上复制的,不同之处在于原文中数据库 url、用户名和密码是写在代码中的,这不符合我们的实际,因而稍微做了修改,使得该类可以直接从配置文件中获取相关的值
ConnectionFactory.java
package com.bestcxx.mavenstu.mavenssh.util;import java.sql.Connection;import java.sql.SQLException;import java.util.Properties; import javax.sql.DataSource; import org.apache.commons.dbcp.DriverManagerConnectionFactory;import org.apache.commons.dbcp.PoolableConnection;import org.apache.commons.dbcp.PoolableConnectionFactory;import org.apache.commons.dbcp.PoolingDataSource;import org.apache.commons.pool.impl.GenericObjectPool; public class ConnectionFactory {final private static String jdbcurl=CustomizedPropertyPlaceholderConfigurer.getContextProperty("jdbc.url");final private static String jdbcusername=CustomizedPropertyPlaceholderConfigurer.getContextProperty("jdbc.username");final private static String jdbcpassword=CustomizedPropertyPlaceholderConfigurer.getContextProperty("jdbc.password");private static interface Singleton { final ConnectionFactory INSTANCE = new ConnectionFactory(); } private final DataSource dataSource; private ConnectionFactory() { Properties properties = new Properties(); properties.setProperty("user", jdbcusername); properties.setProperty("password", jdbcpassword); // or get properties from some configuration file GenericObjectPool<PoolableConnection> pool = new GenericObjectPool<PoolableConnection>(); DriverManagerConnectionFactory connectionFactory = new DriverManagerConnectionFactory( jdbcurl, properties ); new PoolableConnectionFactory( connectionFactory, pool, null, "SELECT 1", 3, false, false, Connection.TRANSACTION_READ_COMMITTED ); this.dataSource = new PoolingDataSource(pool); } public static Connection getDatabaseConnection() throws SQLException { return Singleton.INSTANCE.dataSource.getConnection(); }}
这样就需要新写一个类CustomizedPropertyPlaceholderConfigurer.java
这个类继承自PropertyPlaceholderConfigurer,而后者熟悉Spring的话一定可以认出来,其就是Spring用于加载常量配置文件的方法
可以参考Spring 加载标准属性值配置文件application.properties的两种方式
CustomizedPropertyPlaceholderConfigurer.java的内容
package com.bestcxx.mavenstu.mavenssh.util;import java.util.HashMap;import java.util.Map;import java.util.Properties;import org.springframework.beans.BeansException;import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;/** * 自定义PropertyPlaceholderConfigurer返回properties内容 * Spring的applicationContext.xml的 * <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> * 需要改变为 * <bean class="本类路径.CustomizedPropertyPlaceholderConfigurer"> */public class CustomizedPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {private static Map<String, String> ctxPropertiesMap;@Overrideprotected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess,Properties props) throws BeansException {super.processProperties(beanFactoryToProcess, props);ctxPropertiesMap = new HashMap<String, String>();for (Object key : props.keySet()) {String keyStr = key.toString();String value = props.getProperty(keyStr);ctxPropertiesMap.put(keyStr, value);}}public static String getContextProperty(String name) {return ctxPropertiesMap.get(name);}}
然后,正如该类中的注释中声明的那样,需要修改一下 applicationContext.xml的获取配置*.properties文件的那部分代码
<!-- 定义受环境影响易变的变量 --><!-- <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> --><bean class="com.bestcxx.mavenstu.mavenssh.util.CustomizedPropertyPlaceholderConfigurer"><!-- 覆盖重写这个类,可以在java代码中获取加载文件的值key-value形式 --><property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" /><property name="ignoreResourceNotFound" value="true" /><property name="locations"><list><!-- 数据库配置 --><value>classpath:config/jdbc.properties</value></list></property></bean>
jdbc.properties的内容也贴一下
#jdbc settingsjdbc.driverClassName=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/testjdbc.username=*jdbc.password=*jdbc.initialSize=5jdbc.maxActive=10#hibernate settingshibernate.dialect=org.hibernate.dialect.MySQLDialecthibernate.show_sql=falsehibernate.format_sql=falsehibernate.hbm2ddl.auto=update
这里涉及到 hibernaye.hbm2ddl.auto=update 表不存在则创建表,表已存在若存在改变则更新表,其应用也是在applicationContext.xml中
<!-- 声明Hibernate 的 Session 工厂--><bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"><property name="dataSource" ref="dataSource"/><!-- model里含有具体的实体类若干 --><property name="packagesToScan" value="com.bestcxx.mavenstu.mavenssh.model"/><property name="hibernateProperties"><props><prop key="hibernate.dialect">${hibernate.dialect}</prop><prop key="hibernate.show_sql">${hibernate.show_sql}</prop><prop key="hibernate.format_sql">${hibernate.format_sql}</prop><prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop><!--自动建表 http://www.cnblogs.com/feilong3540717/archive/2011/12/19/2293038.html --></props></property></bean>
当然,如果你觉得这样很麻烦,可以手动建表,也可以把数据库url、用户名和密码写在代码中
8.3、然后是log4j2.xml的配置
<?xml version="1.0" encoding="UTF-8"?><Configuration status="WARN" monitorInterval="300"><!-- 每隔300秒重新读取配置文件,对web应用很实用 --> <Appenders> <!-- 日志输入到数据库 --> <!-- 必须先创建表结构,所以建议保留日志表实体,在项目启动时自动创建或更新表 --> <JDBC name="databaseAppender" tableName="LOGGER"> <ConnectionFactory class="com.bestcxx.mavenstu.mavenssh.util.ConnectionFactory" method="getDatabaseConnection" /> <!-- mysql 设置主键自增策略,对于数据库不支持的则开启下面这字段 <Column name="EVENT_ID" literal="LOGGER_SEQUENCE.NEXTVAL" /> --> <Column name="EVENT_DATE" isEventTimestamp="true" /> <Column name="LEVEL" pattern="%level" /> <Column name="LOGGER" pattern="%logger" /> <Column name="MESSAGE" pattern="%message" /> <Column name="THROWABLE" pattern="%ex{full}" /> </JDBC> </Appenders> <Loggers><!-- 日志类别 --> <!-- 定义根日志类别 查看level http://blog.csdn.net/techq/article/details/6636287--> <Root level="trace"> <AppenderRef ref="databaseAppender" /> </Root> <!-- 保存到数据库 --> <Logger name="databaseAppender" additivity="false" level="INFO"><!--additivity="false" 不再输出父级日志 --> <AppenderRef ref="databaseAppender" /> </Logger> </Loggers> </Configuration>
8.4、测试代码
package com.bestcxx.mavenstu.mavenssh.util;import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.test.annotation.DirtiesContext;import org.springframework.test.annotation.Rollback;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@DirtiesContext@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations={"classpath:spring/applicationContext.xml"})//@TransactionConfiguration(transactionManager = "defaultTransactionManager",defaultRollback=false)//事务管理 @Rollback(false)public class LoggerDaoImplTest {@Testpublic void testAddLogger(){//Logger logger = LogManager.getLogger(LoggerDaoImplTest.class); Logger logger = LogManager.getLogger("databaseAppender"); logger.trace("trace level"); logger.debug("debug level"); logger.info("info level"); logger.warn("warn level"); logger.error("error level"); logger.fatal("fatal level"); }}
效果
9、日志保存到数据库(必看)的最佳实践-log4j2的启动在spring加载配置文件之前
在上面的日志保存到数据库的例子中,由于测试的缘故,我们把日志的声明写在了方法体中,类似于下面的
@Testpublic void testLog4j2(){Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);
但是在实际的运用中,我们总是习惯于把日志对象声明为所在类的全局变量,也就是下面这种
@Controller@SuppressWarnings("serial") public class PersonAction extends BaseAction<Person> {private Logger logger=LogManager.getLogger(PersonAction.class);
但是以目前的项目配置会出问题,会报空指针,经排查是由于log4j2在这种情况下,使用spring加载的配置文件来获取参数的时候,获取的参数为null,更
直白的说就是log4j2要连接数据库的时候,spring还没有加载或者没有加载完配置文件,所以需要对代码进行修改,改动也非常小,java获取spring中配置文件
的工具类还是可以留着的,这不过log4j2连接数据库的用户名、密码、url采取直接从配置文件读取了,绕过了spring。
修改ConnectionFactory.java 为如下即可
package com.bestcxx.mavenstu.mavenssh.util;import java.io.IOException;import java.io.InputStream;import java.sql.Connection;import java.sql.SQLException;import java.util.Properties; import javax.sql.DataSource; import org.apache.commons.dbcp.DriverManagerConnectionFactory;import org.apache.commons.dbcp.PoolableConnection;import org.apache.commons.dbcp.PoolableConnectionFactory;import org.apache.commons.dbcp.PoolingDataSource;import org.apache.commons.pool.impl.GenericObjectPool; public class ConnectionFactory {/*final private static String jdbcurl=CustomizedPropertyPlaceholderConfigurer.getContextProperty("jdbc.url");final private static String jdbcusername=CustomizedPropertyPlaceholderConfigurer.getContextProperty("jdbc.username");final private static String jdbcpassword=CustomizedPropertyPlaceholderConfigurer.getContextProperty("jdbc.password");*/private static interface Singleton { final ConnectionFactory INSTANCE = new ConnectionFactory(); } private final DataSource dataSource; private static InputStream inStream = ConnectionFactory.class.getClassLoader().getResourceAsStream("config/jdbc.properties"); private static Properties prop = new Properties();private ConnectionFactory() {try {prop.load(inStream);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}String jdbcusername = prop.getProperty("jdbc.username");//数据库连接用户名String jdbcpassword = prop.getProperty("jdbc.password");//数据库连接密码String jdbcurl = prop.getProperty("jdbc.url");//数据库连接urlProperties properties = new Properties();properties.setProperty("user", jdbcusername);properties.setProperty("password", jdbcpassword); // or get properties from some configuration file GenericObjectPool<PoolableConnection> pool = new GenericObjectPool<PoolableConnection>(); DriverManagerConnectionFactory connectionFactory = new DriverManagerConnectionFactory( jdbcurl, properties ); new PoolableConnectionFactory( connectionFactory, pool, null, "SELECT 1", 3, false, false, Connection.TRANSACTION_READ_COMMITTED ); this.dataSource = new PoolingDataSource(pool); } public static Connection getDatabaseConnection() throws SQLException { return Singleton.INSTANCE.dataSource.getConnection(); }}jdbc.properties 的位置
config/jdbc.properties 作为常量其实可以保存到枚举类中
private static InputStream inStream = ConnectionFactory.class.getClassLoader().getResourceAsStream(EnumUtil.COMMON_DATABASE_PROPERTIES.toString());
如果你还没有加入github 请先阅读 http://blog.csdn.net/bestcxx/article/details/63687217
本文为博主原创,转载请声明出处:http://blog.csdn.net/bestcxx/article/details/54564687
- APACHE LOG4J™ 2 学习笔记-log4j2 环境部署到各种类型输出+maven\mysql\滚动文件\控制台\异步\过滤器
- log4j文件配置properties,输出到控制台,文件,数据库等各种配置
- log4j输出到控制台
- log4j日志输出到控制台
- Log4j输出到控制台成功,写入文件失败
- log4j的配置及使用,输出到文件和控制台,不同包输出到不同文件
- java学习:log4j输出xml格式的日志文件(log4j2篇)
- war包部署tomcat下,项目中log4j2日志不输出到文件中
- log4j, log4j2 实用配置;log4j 2 异步配置
- Log4j 2 同时输出日志到控制台和文件
- Log4j输出到控制台成功,写入文件失败 - Log4j和commons log的整合
- Log4j输出到控制台顺利,写入文件失败 - Log4j和commons log的整合
- Log4j输出到控制台顺利,写入文件失败 - Log4j和commons log的整合
- eclipse中log4j无法输出到控制台
- IDEA log4j输出到控制台乱码
- log4j能输出控制台但不能输出到文件的问题
- Apache Log4j 学习笔记
- Apache Log4j 学习笔记
- 面向对象的设计原则和设计模式
- Mac OS下包管理器Homebrew的安装与使用
- LeetCode 487. Max Consecutive Ones II
- A - Lesha and array splitting
- *.do的项目
- APACHE LOG4J™ 2 学习笔记-log4j2 环境部署到各种类型输出+maven\mysql\滚动文件\控制台\异步\过滤器
- OpenCV3.0 Examples学习笔记(12)-houghlines.cpp-通过HoughLinesP函数实现直线检测
- JZOJ 3853. 【NOIP2014八校联考第2场第2试9.28】帮助Bsny(help)
- [00807]调用父类方法
- Leetcode 461. Hamming Distance
- Word Ladder--思路一
- SQLiteDatabase 及 ContentProvider 笔记
- 【JZOJ3823】遇见
- 31 Python 多进程-multiprocessing