有关SpringBoot总结
一、前言:本文包括但不限于SpringBoot知识
二、有关SpringBoot的讲解。
1.SpringBoot是一款Spring家族的微服务框架,贯穿一个规则:约定大于配置!!!!通过多个服务之间定义良好的接口和契约联系起来,职责范围明确很重要!
2.SpringBoot并不是一门新的框架,它更像是一个组合。把原本需要繁琐配置的程序,简化为可以无需配置即可立即运行的程序(jar文件)。
做过SpringMVC的人,最头痛的就是各种配置,web.xml,spring配置,数据库配置等等等等。但是我们还发现,每次配置的东西都大体相同,无非是个别地方改一改,但是却要每次都配置一遍。
SpringBoot替我们解决了这一点,如果没有特殊要求,那么将按照默认配置进行操作,即约定大于配置。
3.SpringBoot集成了很多组件,内嵌jetty,tomcat等容器,支持多种持久层框架(我只用过mybatis,jdbc)。这主要是由于提供了starter模式的使用包,使得内嵌成为可能。
由于内嵌了tomcat和jetty容器,所以Springboot可以打包为jar或者war包。jar包的情况下可直接java -jar xxx.jar运行(如果需要读取文件,且文件也需要打包进jar的慎用,否则会出现路径错误问题)。
如果是war包,就直接放进外部配置好的tomcat的webapp下即可。
4.SpringBoot配置文件。它支持yml文件或property文件。我更喜欢用yml一点,因为更加方便、直观、简洁。
5.SpringBoot是微服务框架,最好每个服务有明确的负责范围,在一组或者多组服务器上部署多个服务来完成功能(不要和分布式搞混)。
三、根据Demo进行简单剖析
1.首先通过maven创建一个maven程序,然后再pom.xml里加入下列依赖(如果发现不需要的可进行删减,注意要修改红色标识的g a v)。
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.3.RELEASE</version> <relativePath/> </parent> <groupId>com.kh</groupId> <artifactId>pds</artifactId> <version>2.0</version> <packaging>jar</packaging> <name>PDS</name> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <druid.version>1.1.9</druid.version> <guava.version>19.0</guava.version> <mybatisPlus.verison>3.1.1</mybatisPlus.verison> <shiro.spring.version>1.4.0</shiro.spring.version> <hutool.version>4.5.11</hutool.version> <poi.version>3.7</poi.version> <thymeleaf-version>2.1.7.RELEASE</thymeleaf-version> <fastjson-version>1.2.59</fastjson-version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>${mybatisPlus.verison}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring-boot-web-starter</artifactId> <version>${shiro.spring.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <!--<scope>provided</scope>--> </dependency> <!-- 测试 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- 正对配置文件优化 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> <!-- SQLServer 数据库驱动程序 --> <dependency> <groupId>com.microsoft.sqlserver</groupId> <artifactId>mssql-jdbc</artifactId> <scope>runtime</scope> </dependency> <!-- druid数据库连接池 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>${druid.version}</version> </dependency> <!-- pojo方法简化 --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!-- google guava --> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>${guava.version}</version> </dependency> <!-- 工具增强包 --> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>${hutool.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> <version>${thymeleaf-version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>${fastjson-version}</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>${poi.version}</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>${poi.version}</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-scratchpad</artifactId> <version>${poi.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <fork>true</fork> </configuration> </plugin> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.2</version> <configuration> <verbose>true</verbose> <overwrite>true</overwrite> </configuration> </plugin> </plugins> </build> </project>
2.此时,一个SpringBoot微服务框架已经搭起来了,只需要填充内容即可。首先是配置文件,在resources下创建application.yml文件(注意:没有特殊需求不要修改本文件名),demo如下:
spring:
profiles:
active: dev
说明:由于线上和线下的配置文件大多都不同,所以我们的项目分为开发环境-dev和线上环境prod,上线时只需要修改dev为prod即可,非常方便。如果只是练习的话,可以直接在application写配置而不区分环境。目前我知道的有dev,prod,test(其实只要文件名匹配即可)。
此处贴出demo,可自行百度。在resources下创建application-dev.yml文件(和上面对应)。
#设置应用端口
server:
port: 9527
servlet:
context-path: /xx
spring:
thymeleaf:
prefix: classpath:/static/
cache: false
encoding: UTF-8
enabled: true
http:
encoding:
charset: utf-8
enabled: true
devtools:
restart:
enabled: true
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
druid:
# pfs罪犯电商数据源
master:
url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=xxx
username: xx
password: xx
# 从库数据源
pms:
url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=xx
username: xx
password: xx
pmsr:
url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=x
username: x
password: xx
# 初始连接数
initial-size: 10
# 最大连接池数量
max-active: 100
# 最小连接池数量
min-idle: 10
# 配置获取连接等待超时的时间
max-wait: 60000
# 打开PSCache,并且指定每个连接上PSCache的大小
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
min-evictable-idle-time-millis: 300000
validation-query: SELECT 1
test-while-idle: true
test-on-borrow: false
test-on-return: false
filter:
stat:
log-slow-sql: true
slow-sql-millis: 1000
merge-sql: false
wall:
config:
multi-statement-allow: true
# MyBatis
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
#导出word的模板路径和导出文件路径
word:
path:
root: templates/
source: xx.docx
outPath: xx.docx
sourcePrisoner: xxp.docx
outPathPrisoner: xx.docx
zhangwuPath: xxz.docx
zhangwuOutPath: xx.docx
caimaiPath: xxc.docx
caimaiOutPath: xx.docx
3.看上去已经万事俱备了,接下来创建一个java文件,作为主启动类。需要注意的是,SpringBoot的启动类比较特殊,它会从该类向下自动寻找,所以最好将改启动类放在最外层!!!!
package com.kh.xx; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class PdsApplication { public static void main(String[] args) { SpringApplication.run(PdsApplication.class, args); } }
SpringBootApplication该注解是
@SpringBootConfiguration(对@Configuration的封装,标注当前类是配置类。又相当于@Component表示希望被IOC容器管理)。
@EnableAutoConfiguration(Spring Boot会自动根据你jar包的依赖来自动配置项目)
@ComponentScan(会自动扫描指定包下的全部标有@Component的类,并装入bean容器)三个注解的默认值,可自行百度作用。
4.右键run即可。再次提醒,打包jar时,务必确保没有需要读取的文件被打包进去,否则会出现读取文件失败的情况。如AboutWordParamServiceImp.class.getResource("").getPath()获取当前路径,拼接文件名进行读取文件,会出现jar不可读取的情况!!!!
5.日志。仅供参考,一般小项目可以满足。在resources下创建logback-spring.xml,内容如下:
<?xml version="1.0" encoding="UTF-8"?> <!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 --> <!-- scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true --> <!-- scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 --> <!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 --> <configuration scan="true" scanPeriod="10 seconds"> <!--<include resource="org/springframework/boot/logging/logback/base.xml" />--> <contextName>logback</contextName> <!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 --> <property name="log.path" value="D:/logs/PDS" /> <!-- 彩色日志 --> <!-- 彩色日志依赖的渲染类 --> <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" /> <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" /> <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" /> <!-- 彩色日志格式 --> <property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/> <!--输出到控制台--> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息--> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>info</level> </filter> <encoder> <Pattern>${CONSOLE_LOG_PATTERN}</Pattern> <!-- 设置字符集 --> <charset>UTF-8</charset> </encoder> </appender> <!--输出到文件--> <!-- 时间滚动输出 level为 DEBUG 日志 --> <appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 正在记录的日志文件的路径及文件名 --> <file>${log.path}/log_debug.log</file> <!--日志文件输出格式--> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> <charset>UTF-8</charset> <!-- 设置字符集 --> </encoder> <!-- 日志记录器的滚动策略,按日期,按大小记录 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 日志归档 --> <fileNamePattern>${log.path}/debug/log-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>100MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> <!--日志文件保留天数--> <maxHistory>90</maxHistory> </rollingPolicy> <!-- 此日志文件只记录debug级别的 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>debug</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> </appender> <!-- 时间滚动输出 level为 INFO 日志 --> <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 正在记录的日志文件的路径及文件名 --> <file>${log.path}/log_info.log</file> <!--日志文件输出格式--> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> <charset>UTF-8</charset> </encoder> <!-- 日志记录器的滚动策略,按日期,按大小记录 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 每天日志归档路径以及格式 --> <fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>100MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> <!--日志文件保留天数--> <maxHistory>90</maxHistory> </rollingPolicy> <!-- 此日志文件只记录info级别的 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>info</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> </appender> <!-- 时间滚动输出 level为 WARN 日志 --> <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 正在记录的日志文件的路径及文件名 --> <file>${log.path}/log_warn.log</file> <!--日志文件输出格式--> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> <charset>UTF-8</charset> <!-- 此处设置字符集 --> </encoder> <!-- 日志记录器的滚动策略,按日期,按大小记录 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>100MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> <!--日志文件保留天数--> <maxHistory>90</maxHistory> </rollingPolicy> <!-- 此日志文件只记录warn级别的 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>warn</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> </appender> <!-- 时间滚动输出 level为 ERROR 日志 --> <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 正在记录的日志文件的路径及文件名 --> <file>${log.path}/log_error.log</file> <!--日志文件输出格式--> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> <charset>UTF-8</charset> <!-- 设置字符集 --> </encoder> <!-- 日志记录器的滚动策略,按日期,按大小记录 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 日志归档 --> <fileNamePattern>${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>100MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> <!--日志文件保留天数--> <maxHistory>90</maxHistory> </rollingPolicy> <!-- 此日志文件只记录error级别的 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>error</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> </appender> <!-- <logger>用来设置某一个包或者具体的某一个类的日志打印级别、 以及指定<appender>。<logger>仅有一个name属性, 一个可选的level和一个可选的addtivity属性。 name:用来指定受此logger约束的某一个包或者具体的某一个类。 level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF, 还有一个特俗值INHERITED或者同义词NULL,代表强制执行上级的级别。 如果未设置此属性,那么当前logger将会继承上级的级别。 addtivity:是否向上级logger传递打印信息。默认是true。 --> <!--<logger name="org.springframework.web" level="info"/>--> <!--<logger name="org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor" level="INFO"/>--> <!-- 使用mybatis的时候,sql语句是debug下才会打印,而这里我们只配置了info,所以想要查看sql语句的话,有以下两种操作: 第一种把<root level="info">改成<root level="DEBUG">这样就会打印sql,不过这样日志那边会出现很多其他消息 第二种就是单独给dao下目录配置debug模式,代码如下,这样配置sql语句会打印,其他还是正常info级别: --> <!-- root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性 level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF, 不能设置为INHERITED或者同义词NULL。默认是DEBUG 可以包含零个或多个元素,标识这个appender将会添加到这个logger。 --> <logger name="org.springframework.web" level="info"/> <logger name="org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor" level="info"/> <logger name="com.kh.pds.mapper" level="info"/> <!--开发环境:打印控制台--> <springProfile name="dev"> <root level="debug"> <appender-ref ref="CONSOLE"/> <appender-ref ref="DEBUG_FILE"/> <appender-ref ref="INFO_FILE"/> <appender-ref ref="WARN_FILE"/> <appender-ref ref="ERROR_FILE"/> </root> </springProfile> <!--测试环境:打印控制台和输出到文件--> <springProfile name="test"> <root level="info"> <appender-ref ref="CONSOLE"/> <appender-ref ref="INFO_FILE"/> <appender-ref ref="WARN_FILE"/> <appender-ref ref="ERROR_FILE"/> </root> </springProfile> <!--生产环境:输出到文件--> <springProfile name="prod"> <root level="error"> <appender-ref ref="WARN_FILE"/> <appender-ref ref="ERROR_FILE"/> </root> </springProfile> </configuration>
四、有关于starter
starter是将第三方程序统一配置、集成而给定的入口,可以通过application.yml进行更改。
那么如何开发自己程序的starter包:步骤:
1.需要打成jar包的程序引入spring-boot-configture
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure</artifactId> </dependency>
2.定义接口:
public interface WelcomeInterface { void sayHello(); }
3.编写能够通过application.yml修改的入口
import org.springframework.boot.context.properties.ConfigurationProperties; @ConfigurationProperties("chx.name") public class ConfigProperty { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }
4.编写配置托管到springboot,并给予实例化入口:
@Configuration @ConditionalOnClass //能够让配置类生效 @EnableConfigurationProperties(ConfigProperty.class) public class WelcomeAutoConfiguration { @Bean @ConditionalOnMissingBean public WelcomeInterface start(){ //创建实例 return new WelcomeImp(); } }
5.实现自定义的welcome接口
import org.springframework.beans.factory.annotation.Autowired; public class WelcomeImp implements WelcomeInterface { @Autowired private ConfigProperty config; @Override public void sayHello() { System.out.println("Hello world" + config.getName()); } }
6.能够让springboot自动装配
在resource里的MATE-INF文件夹中(没有就自己创建一个)添加spring.factories文件,加入
org.springframework.boot.autoconfigure.EnableAutoConfiguration=myinterface.WelcomeAutoConfiguration
注意红色字体部分是自己自动装配类的完整路径,即第四步的类。
7.将此程序打包,并加入到springboot的程序中。
利用maven的install功能,打包。在springboot程序中引入此包
<dependency> <groupId>MyUtils</groupId> <artifactId>Configs-starter</artifactId> <version>1.0-SNAPSHOT</version> <scope>compile</scope> </dependency>
在启动类中加入实现类进行测试。
未完待续......