SSM框架在企業中用的很多,許多服務也都建立在此基礎之上,正好,現在入職的公司,也是用的ssm架構。廢話不多說,直接上代碼。
- 環境:JDK8、Idea、maven、git、tomcat8
- 在Idea中新建一個空的maven webapp項目(這個就不用多說了吧大家都會)
- 如圖所示:
. - pom.xml定義一些基本配置比如spring的版本、mybatis的版本、
<!--一些基本的版本依賴配置-->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<!--採用Spring5.x-->
<spring.version>5.1.5.RELEASE</spring.version>
<spring.redis.version>2.1.4.RELEASE</spring.redis.version>
<!--spring aop依賴-->
<aspectjrt.version>1.9.3</aspectjrt.version>
<aspectjweaver.version>1.9.3</aspectjweaver.version>
<mybatis.version>3.4.6</mybatis.version>
<mybatis-spring.version>2.0.0</mybatis-spring.version>
<cglib.version>3.2.5</cglib.version>
<druid.version>1.1.14</druid.version>
<mysql.version>5.1.47</mysql.version>
<redis.version>2.9.0</redis.version>
<fastjson.version>1.2.56</fastjson.version>
<jsp.version>2.2</jsp.version>
<servlet.version>4.0.1</servlet.version>
<jstl.version>1.2</jstl.version>
<slf4j.version>1.7.25</slf4j.version>
<logback-classic.version>1.2.3</logback-classic.version>
<logback-ext-spring.version>0.1.5</logback-ext-spring.version>
<jcl-over-slf4j.version>1.7.25</jcl-over-slf4j.version>
<quartz.version>2.3.0</quartz.version>
<quartz-jobs.version>2.3.0</quartz-jobs.version>
<spring-jackson.version>2.9.8</spring-jackson.version>
<hibernate-validator.version>6.0.13.Final</hibernate-validator.version>
<!--工具類-->
<hutool.version>4.5.10</hutool.version>
</properties>
- pom.xml定義好版本號之後,具體導入依賴,相關jar。
<!--Spring核心包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<!--spring context-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<!--spring-context-support-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<!--spring beans-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<!--spring web-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!--spring aop-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectjrt.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectjweaver.version}</version>
</dependency>
<!--spring tx-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<!--spring websocket-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>${spring.version}</version>
</dependency>
<!--spring orm-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<!--spring oxm-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>${spring.version}</version>
</dependency>
<!--spring orm mybatis-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${mybatis-spring.version}</version>
</dependency>
<!--spring data redis 集成redis-->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>${spring.redis.version}</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>${redis.version}</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!--druid數據源-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<!--cglib代理-->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>${cglib.version}</version>
</dependency>
<!--fastjson-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!--jsp servlet jstl-->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>${jsp.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${servlet.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
<!--日誌框架 slf4j logback-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback-classic.version}</version>
</dependency>
<dependency>
<groupId>org.logback-extensions</groupId>
<artifactId>logback-ext-spring</artifactId>
<version>${logback-ext-spring.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${jcl-over-slf4j.version}</version>
</dependency>
<!--定時任務-->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>${quartz.version}</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>${quartz-jobs.version}</version>
</dependency>
<!--spring jackson整合包-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${spring-jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${spring-jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${spring-jackson.version}</version>
</dependency>
<!--hibernate validator包-->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>${hibernate-validator.version}</version>
</dependency>
<!--Hutool工具類-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
<!--Junit測試包-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
不同環境下的配置文件目錄配置
- 因爲在實際開發過程中,通常我們要配置開發時環境配置、上線時環境配置、以及測試環境配置、這些配置,通常數據庫鏈接redis、定時任務都是不同的(所以我們提取出來)
- 在pom.xml配置Profiles
<!--配置幾個環境下的配置文件目錄-->
<profiles>
<!--開發環境 並且默認-->
<profile>
<id>dev</id>
<properties>
<profiles.active>dev</profiles.active>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<!--test測試-->
<profile>
<id>test</id>
<properties>
<profiles.active>test</profiles.active>
</properties>
</profile>
<!--正式環境-->
<profile>
<id>pro</id>
<properties>
<profiles.active>pro</profiles.active>
</properties>
</profile>
</profiles>
-
既然建立了三個環境下的配置文件,那我們要在resources文件夾新建properties文件夾,然後並新建這三個環境的文件夾,去存放不同環境的配置信息
-
同樣我們也配置config目錄 以及mybatis配置文件目錄,config目錄存放一些基本的配置文件,比如redis.xml、mybati.xml就是將mybatis、redis全都納入Spring容器管理,在resouces根目錄下,我們配置spring-context.xml、spring-mvc.xml。
-
我們看下詳細的目錄配置文件都有哪些並依次配置
-
config目錄:
-
我們依次配置這幾個配置文件
-
annotation.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--spring 掃包 @Service ..... -->
<context:component-scan base-package="com.bootdu"/>
<context:annotation-config/>
</beans>
- beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--bean的配置-->
<!-- 配置 JSR303 Bean Validator 定義 -->
<bean id="validator"
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
<bean id="linkedBlockingQueue" class="java.util.concurrent.LinkedBlockingQueue"/>
</beans>
- jdbc.xml 數據源配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd">
<!-- 數據源配置, 使用 BoneCP 數據庫連接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<!-- 數據源驅動類可不寫,Druid默認會自動根據URL識別DriverClass -->
<property name="driverClassName" value="${jdbc_driverClassName}"/>
<!-- 基本屬性 url、user、password -->
<property name="url" value="${jdbc_url}"/>
<property name="username" value="${jdbc_username}"/>
<property name="password" value="${jdbc_password}"/>
<!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="10"/>
<property name="minIdle" value="5"/>
<property name="maxActive" value="500"/>
<!-- 配置獲取連接等待超時的時間 -->
<property name="maxWait" value="60000"/>
<!-- 配置間隔多久才進行一次檢測,檢測需要關閉的空閒連接,單位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000"/>
<!-- 配置一個連接在池中最小生存的時間,單位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000"/>
<property name="validationQuery" value="SELECT 'x'"/>
<property name="testWhileIdle" value="true"/>
<property name="testOnBorrow" value="true"/>
<property name="testOnReturn" value="false"/>
<!-- 配置監控統計攔截的filters -->
<property name="filters" value="stat"/>
</bean>
</beans>
- mybaits.xml mybatis的配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--mybatis sessionFactory配置 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations" value="classpath:/**/mapper/*Mapper.xml"/>
<property name="configLocation" value="classpath:/mybaits/mybatis-config.xml"></property>
</bean>
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>
<!-- 用於將接口映射爲具體的實例 ,使得在Service中可以直接注入相關的Dao接口來進行數據訪問 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.bootdu.**.mapper"/>
<property value="sqlSessionFactory" name="sqlSessionFactoryBeanName"/>
<property value="sqlSession" name="sqlSessionTemplateBeanName"/>
</bean>
<!--引入數據源配置文件-->
<import resource="jdbc.xml"/>
</beans>
- property.xml 加載resources下的配置文件到spring容器,比如我們數據庫鏈接、redis連接都是寫在配置文件裏邊的。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 讀取配置文件到Spring容器-->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<!-- jdbc配置 -->
<value>classpath:properties/db.properties</value>
<!-- property配置 -->
<value>classpath:properties/property.properties</value>
</list>
</property>
</bean>
</beans>
- redis.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- redis 連接池 -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!-- 最大活動對象數 -->
<property name="maxTotal" value="${redis.pool.maxTotal}"/>
<!-- 最大能夠保持idel狀態的對象數 -->
<property name="maxIdle" value="${redis.pool.maxIdle}"/>
<!-- 最小能夠保持idel狀態的對象數 -->
<property name="minIdle" value="${redis.pool.minIdle}"/>
<!-- 當池內沒有返回對象時,最大等待時間 -->
<property name="maxWaitMillis" value="${redis.pool.maxWaitMillis}"/>
<!-- 當調用borrow Object方法時,是否進行有效性檢查 -->
<property name="testOnBorrow" value="${redis.pool.testOnBorrow}"/>
<!-- 當調用return Object方法時,是否進行有效性檢查 -->
<!-- <property name="testOnReturn" value="${redis.pool.testOnReturn}" /> -->
<!-- 向調用者輸出“鏈接”對象時,是否檢測它的空閒超時; -->
<!-- <property name="testWhileIdle" value="${redis.pool.testWhileIdle}" /> -->
<!-- 對於“空閒鏈接”檢測線程而言,每次檢測的鏈接資源的個數。默認爲3. -->
<!-- <property name="numTestsPerEvictionRun" value="${redis.pool.numTestsPerEvictionRun}" /> -->
<!-- “空閒鏈接”檢測線程,檢測的週期,毫秒數。如果爲負值,表示不運行“檢測線程”。默認爲-1. -->
<!-- <property name="timeBetweenEvictionRunsMillis" value="${redis.pool.timeBetweenEvictionRunsMillis}" /> -->
</bean>
<bean id="redisConnectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="poolConfig" ref="poolConfig"/>
<property name="hostName" value="${redis_url}"></property>
<!---
<property name="password" value="" ></property>
-->
</bean>
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="redisConnectionFactory"></property>
</bean>
<!--後期補充序列化方式,默認的是jdk的-->
</beans>
- threadPool.xml 線程池配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- spring線程池 -->
<bean id="taskExecutor"
class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<!-- 線程池維護線程的最少數量 -->
<property name="corePoolSize" value="50" />
<!-- 線程池維護線程所允許的空閒時間 -->
<property name="keepAliveSeconds" value="600" />
<!-- 線程池維護線程的最大數量 -->
<property name="maxPoolSize" value="200" />
<!-- 線程池所使用的緩衝隊列 -->
<property name="queueCapacity" value="100" />
<!-- 線程池對拒絕任務(無線程可用)的處理策略,目前只支持AbortPolicy、CallerRunsPolicy;默認爲後者 -->
<property name="rejectedExecutionHandler">
<!-- AbortPolicy:直接拋出java.util.concurrent.RejectedExecutionException異常
CallerRunsPolicy:主線程直接執行該任務,執行完之後嘗試添加下一個任務到線程池中,可以有效降低向線程池內添加任務的速度
DiscardOldestPolicy:拋棄舊的任務、暫不支持;會導致被丟棄的任務無法再次被執行
DiscardPolicy:拋棄當前任務、暫不支持;會導致被丟棄的任務無法再次被執行 -->
<bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" />
</property>
</bean>
<!--創建ThreadPoolTaskScheduler實例 -->
<task:scheduler id="taskScheduler" pool-size="10" />
</beans>
- transaction.xml spring註解事務配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- spring 事務 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 開啓事務註解 -->
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
<!--引入jdbc-->
<import resource="jdbc.xml"/>
</beans>
- 我們再次配置mybatis-config.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 全局參數 -->
<settings>
<!-- 使全局的映射器啓用或禁用緩存。 -->
<setting name="cacheEnabled" value="true"/>
<!-- 全局啓用或禁用延遲加載。當禁用時,所有關聯對象都會即時加載。 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 當啓用時,有延遲加載屬性的對象在被調用時將會完全加載任意屬性。否則,每種屬性將會按需要加載。 -->
<setting name="aggressiveLazyLoading" value="true"/>
<!-- 是否允許單條sql 返回多個數據集 (取決於驅動的兼容性) default:true -->
<setting name="multipleResultSetsEnabled" value="true"/>
<!-- 是否可以使用列的別名 (取決於驅動的兼容性) default:true -->
<setting name="useColumnLabel" value="true"/>
<!-- 允許JDBC 生成主鍵。需要驅動器支持。如果設爲了true,這個設置將強制使用被生成的主鍵,有一些驅動器不兼容不過仍然可以執行。 default:false -->
<setting name="useGeneratedKeys" value="false"/>
<!-- 指定 MyBatis 如何自動映射 數據基表的列 NONE:不隱射 PARTIAL:部分 FULL:全部 -->
<setting name="autoMappingBehavior" value="PARTIAL"/>
<!-- 這是默認的執行類型 (SIMPLE: 簡單; REUSE: 執行器可能重複使用prepared statements語句;BATCH:
執行器可以重複執行語句和批量更新) -->
<setting name="defaultExecutorType" value="SIMPLE"/>
<!-- 使用駝峯命名法轉換字段。 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!-- 設置本地緩存範圍 session:就會有數據的共享 statement:語句範圍 (這樣就不會有數據的共享 ) defalut:session -->
<setting name="localCacheScope" value="SESSION"/>
<!-- 設置但JDBC類型爲空時,某些驅動程序 要指定值,default:OTHER,插入空值時不需要指定類型 -->
<setting name="jdbcTypeForNull" value="NULL"/>
<!-- 開啓打印log-->
<!-- <setting name="logImpl" value="STDOUT_LOGGING"/>-->
</settings>
<!--配置包-->
<typeAliases>
<package name="com.bootdu.ssm.entity"/>
</typeAliases>
</configuration>
- 最後創建properties下的配置文件:db.properties、logback.xml、property.properties、quartz-config.xml
- db.properties
#數據庫配置
jdbc_driverClassName=com.mysql.jdbc.Driver
jdbc_url=jdbc:mysql://127.0.0.1:3306/ssm?useSSL=false&useUnicode=true&characterEncoding=UTF-8
jdbc_username=root
jdbc_password=root
#redis配置
redis_url=127.0.0.1
#maximum active objects
redis.pool.maxTotal=500
#maximum idle objects
redis.pool.maxIdle=60
#minimum idle objects
redis.pool.minIdle=40
#maximum wait time when no object is returned in the pool
redis.pool.maxWaitMillis=10000
#When the borrow Object method is called, the validity check is performed
redis.pool.testOnBorrow=true
#When the return Object method is called, the validity check is performed
redis.pool.testOnReturn=true
#"Free link" detects thread, detects cycles, milliseconds. If it is negative, the "detection thread" is not run. The default is -1.
redis.pool.timeBetweenEvictionRunsMillis=30000
#When you output the "link" object to the caller, detect its idle timeout;
redis.pool.testWhileIdle=true
#For the "free link" detection thread, the number of linked resources per check. The default is 3.
redis.pool.numTestsPerEvictionRun=50
logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- 說明: 1、日誌級別及文件 日誌記錄採用分級記錄,級別與日誌文件名相對應,不同級別的日誌信息記錄到不同的日誌文件中 例如:error級別記錄到log_error_xxx.log或log_error.log(該文件爲當前記錄的日誌文件),而log_error_xxx.log爲歸檔日誌,
日誌文件按日期記錄,同一天內,若日誌文件大小等於或大於2M,則按0、1、2...順序分別命名 例如log-level-2013-12-21.0.log
其它級別的日誌也是如此。 2、文件路徑 若開發、測試用,在Eclipse中運行項目,則到Eclipse的安裝路徑查找logs文件夾,以相對路徑../logs。
若部署到Tomcat下,則在Tomcat下的logs文件中 3、Appender FILEERROR對應error級別,文件名以log-error-xxx.log形式命名
FILEWARN對應warn級別,文件名以log-warn-xxx.log形式命名 FILEINFO對應info級別,文件名以log-info-xxx.log形式命名
FILEDEBUG對應debug級別,文件名以log-debug-xxx.log形式命名 stdout將日誌信息輸出到控制上,爲方便開發測試使用 -->
<configuration>
<property name="LOG_PATH" value="${user.dir}/logs"/>
<!-- 日誌記錄器,日期滾動記錄 -->
<appender name="FILEERROR"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在記錄的日誌文件的路徑及文件名 -->
<file>${LOG_PATH}/log_error.log</file>
<!-- 日誌記錄器的滾動策略,按日期,按大小記錄 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 歸檔的日誌文件的路徑,例如今天是2013-12-21日誌,當前寫的日誌文件路徑爲file節點指定,可以將此文件與file指定文件路徑設置爲不同路徑,從而將當前日誌文件或歸檔日誌文件置不同的目錄。
而2013-12-21的日誌文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
<fileNamePattern>${LOG_PATH}/log-error-%d{yyyy-MM-dd}.%i.log
</fileNamePattern>
<!-- 除按日誌記錄之外,還配置了日誌文件不能超過2M,若超過2M,日誌文件會以索引0開始, 命名日誌文件,例如log-error-2013-12-21.0.log -->
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>2MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<!-- 追加方式記錄日誌 -->
<append>true</append>
<!-- 日誌文件的格式 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%-5p [%d][%mdc{mdc_accNo}][%t] %C:%L - %m %n</pattern>
<charset>utf-8</charset>
</encoder>
<!-- 此日誌文件只記錄error級別的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>error</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="FILEWARN"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/log_warn.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/log-warn-%d{yyyy-MM-dd}.%i.log
</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>2MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<append>true</append>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%-5p [%d][%mdc{mdc_accNo}][%t] %C:%L - %m %n</pattern>
<charset>utf-8</charset>
</encoder>
<!-- 此日誌文件只記錄warn級別,不記錄大於warn級別的日誌 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>WARN</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="FILEINFO"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/log_info.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/log-info-%d{yyyy-MM-dd}.%i.log
</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>2MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<append>true</append>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%-5p [%d][%mdc{mdc_accNo}][%t] %C:%L - %m %n</pattern>
<charset>utf-8</charset>
</encoder>
<!-- 此日誌文件只記錄info級別,不記錄大於info級別的日誌 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="FILEDEBUG"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/log_debug.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/log-debug-%d{yyyy-MM-dd}.%i.log
</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>2MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<append>true</append>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%-5p [%d][%mdc{mdc_accNo}][%t] %C:%L - %m %n</pattern>
<charset>utf-8</charset>
</encoder>
<!-- 此日誌文件只記錄debug級別,不記錄大於debug級別的日誌 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>DEBUG</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<Target>System.out</Target>
<encoder>
<pattern>%-5p [%d][%mdc{mdc_accNo}][%t] %C:%L - %m %n</pattern>
</encoder>
<!-- 此日誌appender是爲開發使用,只配置最底級別,控制檯輸出的日誌級別是大於或等於此級別的日誌信息 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
</appender>
<!-- 爲單獨的包配置日誌級別,若root的級別大於此級別, 此處級別也會輸出 應用場景:生產環境一般不會將日誌級別設置爲trace或debug,但是爲詳細的記錄SQL語句的情況,
可將hibernate的級別設置爲debug,如此一來,日誌文件中就會出現hibernate的debug級別日誌, 而其它包則會按root的級別輸出日誌,這個地方還需要再修改,additivity表示只在當前logger輸出,其他logger不再輸出 -->
<!-- 可以打印sql,也可以打印學生卡信息 -->
<logger name="com.ibatis" level="DEBUG" additivity="false"/>
<logger name="com.ibatis.common.jdbc.SimpleDataSource" level="DEBUG"
additivity="false"/>
<logger name="com.ibatis.common.jdbc.ScriptRunner" level="DEBUG"
additivity="false"/>
<logger name="com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate"
additivity="false" level="DEBUG"/>
<logger name="java.sql.Statement" level="DEBUG" additivity="false"/>
<logger name="java.sql.PreparedStatement" level="DEBUG"
additivity="false"/>
<!-- 生產環境,將此級別配置爲適合的級別,以免日誌文件太多或影響程序性能 -->
<root level="DEBUG">
<appender-ref ref="FILEDEBUG"/>
<appender-ref ref="FILEINFO"/>
<appender-ref ref="FILEWARN"/>
<appender-ref ref="FILEERROR"/>
<!-- 生產環境將請stdout去掉 -->
<appender-ref ref="stdout"/>
</root>
</configuration>
property.properties,這個配置文件默認是空的,大家可以自定義一些東西配置到這裏邊,比如resteasy接口調用之類的
quartz-config.xml 定時任務配置
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!--1:配置定時任務bean-->
<bean id="quarzSayHello" class="com.bootdu.quartz.QuartzSayHello"/>
<!--2:定義定時任務的方法-->
<bean id="jobQuarzSayHello" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<ref bean="quarzSayHello"></ref>
</property>
<property name="targetMethod" value="say"/>
</bean>
<!--3定義觸發時間-->
<bean id="doTimeQuarzSayHello" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail">
<ref bean="jobQuarzSayHello"/>
</property>
<!--cron表達式 每五秒 調用一次-->
<property name="cronExpression">
<value>0/5 * * * * ? *</value>
</property>
</bean>
<!--6:配置總管理類 如果將lazy-init設置成false,則容器啓動就會執行調度程序-->
<bean id="startQuartz" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" autowire="no"
lazy-init="false">
<property name="triggers">
<list>
<ref bean="doTimeQuarzSayHello"/>
</list>
</property>
</bean>
</beans>
Java代碼:
package com.bootdu.quartz;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 定時任務
*/
public class QuartzSayHello {
private Logger logger = LoggerFactory.getLogger(QuartzSayHello.class);
/**
* 定義執行的方法
*/
public void say(){
logger.info("say hello quraz .....");
}
}
- test、pro文件與dev 文件名都一樣,可能就是裏邊的數據庫連接等地址密碼、token變了,根據自己情況而定。
- 我們把配置文件都建好了,那麼我們如果將這些配置文件納入spring容器管理呢、這裏用的方法很簡單,spring-context.xml,我們直接將config的文件引入到spring-context.xml這樣就引入到spring容器管理了。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<context:annotation-config />
<!--spring context默認加載所有文件-->
<import resource="config/*.xml" />
</beans>
- 我們再次配置spring-mvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<!--spring mvc的配置-->
<!-- 自動掃描該包,使SpringMVC認爲包下用了@controller註解的類是控制器 -->
<context:component-scan base-package="com.bootdu.ssm.controller"/>
<!--start:使用Jackson 2.x的配置,需要導入的jar包:jackson-core-xxx.jar、jackson-annotations-xxx.jar、jackson-databind-xxx.jar-->
<!--通過處理器映射DefaultAnnotationHandlerMapping來開啓支持@Controller註解-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" />
<!--通過處理器適配器AnnotationMethodHandlerAdapter來開啓支持@RequestMapping註解-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<!-- 設置返回字符串編碼 -->
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name = "supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
<!-- json轉換器 -->
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
</list>
</property>
</bean>
<!--end-->
<!-- 定義跳轉的文件的前後綴 ,視圖模式配置-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 這裏的配置我的理解是自動給後面action的方法return的字符串加上前綴和後綴,變成一個 可用的url地址 -->
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--文件上傳配置待補充-->
</beans>
- 最新我們配置web.xml
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>ssm++mysql+redis+quarz</display-name>
<!-- Spring配置 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring-context.xml</param-value>
</context-param>
<!-- SpringMVC核心分發器 -->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:/spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- spring mvc編碼處理 -->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--設置啓動頁-->
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/index</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index</welcome-file>
</welcome-file-list>
</web-app>
- 我們創建進行一個student庫,實體,service、controller,進行測試,這裏可以自定義一個表任何都可以,沒必要跟我一樣,只要能夠正常從數據庫讀取數據,就證明成功了,注意mapper.xml要放在resources文件夾下,並且要與我們java目錄下的接口同名,不然掃描不進去。
- 是不是該運行項目了?No No No,我們還沒有配置完,我們上邊配置了,我們開發環境下配置文件,測試環境下配置文件,以及,正式環境配置,那麼我們需要maven幫我們打包的時候,去幫我們去把不同環境的配置文件打包上去,我們在pom.xml裏邊build裏邊配置。
<build>
<!--resources下文件配置-->
<resources>
<resource>
<directory>src/main/resources/</directory>
<excludes>
<exclude>properties/*</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources/properties/${profiles.active}</directory>
<excludes>
<exclude>*.xml</exclude>
</excludes>
<targetPath>properties</targetPath>
</resource>
<resource>
<directory>src/main/resources/properties/${profiles.active}</directory>
<excludes>
<exclude>*.properties</exclude>
<exclude>logback.xml</exclude>
</excludes>
<targetPath>config</targetPath>
</resource>
<resource>
<directory>src/main/resources/properties/${profiles.active}</directory>
<excludes>
<exclude>*.properties</exclude>
<exclude>quartz-config.xml</exclude>
</excludes>
</resource>
</resources>
<finalName>ssm</finalName>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
<!--對於maven構建的項目,由於idea中maven的配置優先,需要在pom.xml中對maven-surefire-plugin進行配置。-->
<configuration>
<forkMode>once</forkMode>
<argLine>-Dfile.encoding=UTF-8</argLine>
</configuration>
</plugin>
<plugin>
<groupId>com.artofsolving</groupId>
<artifactId>jodconverter-maven-plugin</artifactId>
<version>2.2.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<warName>bootdu</warName>
</configuration>
</plugin>
<!-- findbugs插件 -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>3.0.5</version>
<configuration>
<!-- 設置分析工作的等級,可以爲Min、Default和Max -->
<effort>Default</effort>
<!-- Low、Medium和High (Low最嚴格) -->
<threshold>Medium</threshold>
<failOnError>false</failOnError>
<findbugsXmlOutput>true</findbugsXmlOutput>
<findbugsXmlOutputDirectory>${project.build.directory}/findbugs</findbugsXmlOutputDirectory>
</configuration>
<executions>
<execution>
<id>run-findbugs</id>
<!--在compile 階段觸發執行findbugs檢查,比如執行 mvn compile,mvn clean package,mvn clean install-->
<phase>compile</phase>
<goals>
<goal>findbugs</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.3</version>
<configuration>
<destFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</destFile>
<dataFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</dataFile>
<output>file</output>
<append>true</append>
</configuration>
<executions>
<execution>
<id>pre-unit-test</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<propertyName>surefireArgLine</propertyName>
</configuration>
</execution>
<execution>
<id>post-unit-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<outputDirectory>${project.reporting.outputDirectory}/jacoco-ut</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
24. 我們打勾不同的profile,在執行編譯打包就會幫我們把不同環境下的配置文件打包進去啦。那麼我們,直接idea部署tomcat,直接運行,瀏覽器輸出:
25.
26. 控制檯輸出:我們的cron配置的是每隔五秒執行一次