需求
從今天開始花一些時間來搭建springboot項目,構(gòu)建的需求
- 初始化springboot的maven項目
- 引入數(shù)據(jù)源連接mysql數(shù)據(jù)庫
- 引入orm框架
- 基礎配置
- 引入分頁
- 引入日志
構(gòu)建項目
- 地址:http://start.spring.io/
- Jdk版本1.8及以上
image.png
- 如你所見,項目里面基本沒有代碼耘子,除了幾個空目錄外,還包含如下幾樣東西吸耿。
pom.xml:Maven構(gòu)建說明文件制妄。
DemoApplication.java:一個帶有main()方法的類掸绞,用于啟動應用程序(關(guān)鍵)。
DemoApplicationTests.java:一個空的Junit測試類,它加載了一個使用Spring Boot字典配置功能的Spring應用程序上下文衔掸。
application.properties:一個空的properties文件烫幕,你可以根據(jù)需要添加配置屬性。
初始化代碼
創(chuàng)建TestController類敞映,添加如下代碼较曼。
@RestController
@EnableAutoConfiguration
public class TestController {
@RequestMapping("/")
public String test() {
return "Hello world";
}
}
啟動程序
在DemoApplication.java 文件點擊右鍵運行main方法(也可以另外一種啟動方式:
mvn spring-boot:run -Dspring.profiles.active=dev
),之后運行http://localhost:8080/就會看到Hello world
了振愿。
- 注意一點:DemoApplication這個啟動類必須放在最外層捷犹,要不會抱一個錯誤
Whitelabel Error Page
,詳細解釋也可以看官網(wǎng)http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#using-boot-structuring-your-code
代碼規(guī)范
接下來我們做一下代碼規(guī)范要求,以后都按照這種格式統(tǒng)一書寫冕末。
業(yè)務分層
- domain層:實體類萍歉。
- api層:對外接口。
- service層:業(yè)務層档桃。
- dao層:持久層枪孩。
- Controller層:控制層。
pom文件配置
以下是基礎jar文件:
<dependencies>
<!-- base -->
<dependency>
<groupId>com.lulj</groupId>
<artifactId>bruce-bean</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
<!-- spring boot start -->
<!--核心模塊胳蛮,包括自動配置支持销凑、日志和YAM-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!--測試模塊,包括JUnit仅炊、Hamcrest斗幼、Mockito-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--支持web的模塊-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--引用AOP-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!--啟動時啟動內(nèi)置tomcat -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<!-- 集成log-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
<!-- MyBatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.1</version>
</dependency>
<!--mapper-->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>1.2.4</version>
</dependency>
<!-- 熱部署,不用重啟 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<!-- 添加freemarker依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<!-- spring boot end -->
<!--spring2.0集成redis所需common-pool2-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
<!-- 將作為Redis對象序列化器 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
</dependency>
<!-- MySql驅(qū)動 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- 集成druid抚垄,使用連接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.0</version>
</dependency>
<!-- lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>
<!--pagehelper-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
</dependency>
框架配置
在resources目錄下新建application.properties或者application.yml配置文件蜕窿,本文使用properties,添加如下配置:
#公共配置與profiles選擇無關(guān)
mybatis.typeAliasesPackage=com.example.demo.domain
mybatis.mapperLocations=classpath*:com/example/demo/dao/**/*Mapper.xml
configuration.cacheEnabled=true
configuration.useGeneratedKeys=true
configuration.defaultExecutorType=REUSE
configuration.log-imp=LOGBACK
#駝峰標識
configuration.mapUnderscoreToCamelCase=true
configuration.jdbcTypeForNull=NULL
#sql日志
logging.level.com.example.demo..dao=DEBUG
###########################################開發(fā)配置###########################################
#端口
server.port=8080
#項目名稱
server.servlet.context-path=/demo
#服務名稱
spring.application.name=demo
###mysql驅(qū)動配置信息
spring.datasource.url=jdbc:mysql://192.168.179.191:3306/wx?useUnicode=true&useSSL=false&characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
# 連接池的配置信息
spring.datasource.filters=stat
spring.datasource.maxActive=20
spring.datasource.initialSize=1
spring.datasource.maxWait=60000
spring.datasource.minIdle=1
spring.datasource.timeBetweenEvictionRunsMillis=60000
spring.datasource.minEvictableIdleTimeMillis=300000
spring.datasource.validationQuery=select 'x'
spring.datasource.testWhileIdle=true
spring.datasource.testOnBorrow=false
spring.datasource.testOnReturn=false
poolPreparedStatements=true
spring.datasource.maxOpenPreparedStatements=20
########分頁#######
pagehelper.helperDialect=mysql
pagehelper.reasonable=true
pagehelper.supportMethodsArguments=true
pagehelper.params=count=countSql
pagehelper.offset-as-page-num=true
pagehelper.row-bounds-with-count=true
引入日志配置
SpringBoot 的日志文件放在resources目錄下呆馁,在resources目錄下新建logback.xml.
logback.xml配置及說明
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright 2010-2011 The myBatis Team Licensed under the Apache License,
Version 2.0 (the "License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
OR CONDITIONS OF ANY KIND, either express or implied. See the License for
the specific language governing permissions and limitations under the License. -->
<configuration>
<contextName>demo</contextName>
<property name="log.name" value="demo" />
<property name="log.dir" value="../logs" />
<appender name="FILEERROR"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.dir}/log_error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.dir}/error/${log.name}-error-%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>[%date{ISO8601}] [%-5level] - [%thread] [%X{requestId}] [%logger] [%X{akkaSource}] - %msg
%rootException %n
</pattern>
<charset>utf-8</charset>
</encoder>
<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.dir}/${log.name}_warn.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.dir}/warn/${log.name}-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>[%date{ISO8601}] [%-5level] - [%thread] [%X{requestId}] [%logger] [%X{akkaSource}] - %msg
%rootException %n
</pattern>
<charset>utf-8</charset>
</encoder>
<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.dir}/${log.name}_info.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.dir}/info/${log.name}-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>[%date{ISO8601}] [%-5level] - [%thread] [%X{requestId}] [%logger] [%X{akkaSource}] - %msg
%rootException %n
</pattern>
<charset>utf-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>info</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>
%black() %red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight([%-5level]) %cyan([%X{requestId}]) %boldMagenta([%logger]) [%X{akkaSource}] - %cyan(%msg
%rootException %n)
</pattern>
<charset>utf-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>debug</level>
</filter>
</appender>
<logger name="org.springframework" level="WARN" />
<logger name="org.hibernate" level="WARN" />
<root level="INFO">
<appender-ref ref="FILEERROR" />
<appender-ref ref="FILEWARN" />
<appender-ref ref="FILEINFO" />
<!-- 生產(chǎn)環(huán)境將請stdout,testfile去掉 -->
<appender-ref ref="STDOUT" />
</root>
</configuration>
日志統(tǒng)一管理
@Aspect
@Order(-99)
@Configuration
@Slf4j
public class LogConfig {
@Pointcut("execution(* com.example.demo.controller..*.*(..))," +
"execution(* com.example.demo.api..*.*(..))")
public void executionService() {
}
@Before(value = "executionService()")
public void doBefore(JoinPoint joinPoint) {
String requestId = String.valueOf(UUID.randomUUID());
MDC.put("requestId", requestId);
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
log.info("HTTP URL : " + request.getRequestURL().toString());
log.info("HTTP METHOD : " + request.getMethod());
log.info("IP : " + IPAddrUtil.localAddress());
log.info("CLASS METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "."
+ joinPoint.getSignature().getName());
log.info("PARAMS : " + Arrays.toString(joinPoint.getArgs()));
}
@AfterReturning(pointcut = "executionService()", returning = "returnValue")
public void doAfterReturning(Object returnValue) {
log.info("=====>@AfterReturning:The response parameter is:{}", returnValue);
MDC.clear();
}
@Around("executionService()")
public Object timeAround(ProceedingJoinPoint joinPoint) {
long startTime = System.currentTimeMillis();
Object obj = null;
try {
obj = joinPoint.proceed();
} catch (Throwable e) {
log.error("=====>Counts the elapsed time of a method execution to surround notification errors:", e);
}
long endTime = System.currentTimeMillis();
log.info("=====>Processing this request takes time:{} ms", endTime - startTime);
return obj;
}
}
說明
- 本文只做學習參考桐经,如有任何不準確的地方歡迎指正。
- 源碼參考 :https://gitee.com/lulongji/springboot-demo.git
- 我的郵箱:
lulongji2011@163.com
版權(quán)聲明:
本文為博主原創(chuàng)文章浙滤,轉(zhuǎn)載請附上原文出處鏈接和本聲明阴挣。