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());


完整的ssh代码请查看 https://github.com/Bestcxy/SSH-ajax-axis2-maven-log4j-redis

如果你还没有加入github 请先阅读 http://blog.csdn.net/bestcxx/article/details/63687217


本文为博主原创,转载请声明出处:http://blog.csdn.net/bestcxx/article/details/54564687











0 0
原创粉丝点击