它是spring的脚手架,能够快速构建项目,提高开发效率。一个引导spring项目创建、启动的工具。
优点:配置简单;无需依赖外部的Servlet容器;项目可独立运行;提供自动装配、依赖管理、应用监控功能。
启动类的位置是不是跟controller/pojo/service等目录同一级,不是的话就无法正常显示,因为启动类有默认的包扫描路径。
修改conf/settings.xml,可参考网上,或者根据公司提供的
配置profile,适应不同开发环境,可配置多套。
<profile>
<id>jdk-1.8id>
<activation>
<activeByDefault>trueactiveByDefault>
<jdk>1.8jdk>
activation>
<properties>
<maven.compiler.source>1.8maven.compiler.source>
<maven.compiler.target>1.8maven.compiler.target>
<maven.compiler.compilerVersion>1.8maven.compiler.compilerVersion>
properties>
profile>
配置阿里镜像,加速jar包下载
<mirror>
<id>aliyunid>
<name>aliyunname>
<mirrorOf>centralmirrorOf>
<url>https://maven.aliyun.com/repository/centralurl>
mirror>
法1:idea创建maven项目,new project ==> Maven
分别在pom.xml中导入父工程和开发场景依赖,例如web开发依赖
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.3.7.RELEASEversion>
parent>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
dependencies>
法2:idea创建项目时,选择Spring Initailizr,new project ==> Spring Initailizr ==>选择需要的场景
这种方式会自动引入依赖、构建项目结构、编写好主配置类
法3:通过Spring Boot CLI来运行groovy脚本,安装见链接里面的OSX Homebrew Installation,一共就两命令,它无需idea构建模版代码,即可实现一个spring应用
$ brew tap spring-io/tap
$ brew install spring-boot
如果命令报错,根据提示进行安装即可,像我这边第二个没有xcode-select,具体使用参考JAR Support and Groovy Support
只需在application.properties(或.yaml)文件中进行配置。
在pom.xml中配置插件,就能将项目打成可执行的jar包,也能配置排除那些依赖(后面会提到)
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
打包:package 清理:clean
执行jar包:java -jar jar包名.jar
生成的jar包位置可通过控制台查看。
如果没有配置插件,执行时报错:jar包名.jar中没有主清单属性.
每次打包前先clean,清除旧的jar包
tfboot
不同环境有不同配置,通过在application.properties配置profiles,来引入不同环境下的配置文件。
application.properties 主配置文件
application-prod1.properties 生产环境1
application-prod2.properties 生产环境2
application-test.properties 测试环境
在application.properties引入
#生产环境
spring.profiles.active=prod1,prod2
#测试环境
#spring.profiles.active=test
如有重复配置(application.properties中已经配置),以引入的为准。
执行jar包时也可通过指定不同环境运行,而无需去修改配置文件再重新打包
java -jar xxx.jar --spring.profiles.active=test
甚至可以通过修改配置文件中的其它内容
java -jar xxx.jar --spring.profiles.active=test --person.name=haha
这里的注解的含义是指读取哪个配置文件,而不是代表环境所使用的配置文件,环境最终的配置文件是由spring.profiles.active
决定。
@Profile(value = “xxx”)
value="default"对 应application.properties
application-prod.properties
person.name=boss
application-prod1.properties
person.age=22
application-test.properties
person.name=worker
person.age=18
public interface Person {
}
@Profile(value = "test")
@Component //注入容器
@ConfigurationProperties(value = "person") //配置绑定
@Data
public class Worker implements Person{
String name;
Integer age;
}
@Profile(value = {"prod","prod1","default"}) //默认
@Component
@ConfigurationProperties(value = "person")
@Data
public class Boss implements Person{
String name;
Integer age;
}
//controller测试
@Autowired
Person person;
@RequestMapping("/pps")
public Object getDiffPerson(){
return person.toString();
}
/Users/zone/IdeaProjects/boot/src/main/java/com/zone/z1
如果只是某个配置项不同,可使用@ConditionalOnProperty进行配置,因为Profile一般是针对一个配置文件的,也就是一个环境的配置,例如它可以根据配置项的值决定注入哪个类
参考:链接
boot项目
父项目做依赖管理:spring-boot-starter-parent,它的父项目声明了常用依赖的版本号,有版本仲裁机制,能防止版本冲突,即项目引入各种依赖时,无需声明版本号。除此之外,父工程还有另外两种实现方式
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-dependenciesartifactId>
<version>2.3.7.RELEASEversion>
parent>
但对于版本冲突的依赖,需要在pom.xml中配置自己指定的版本号
<properties>
<mysql.version>5.6.49mysql.version>
properties>
起步依赖
例如各种场景启动器:Starters ,将每个场景的依赖都整合到一个Starters依赖,让用户避免繁杂依赖导入的困扰。它会根据不同开发场景导入所需要的依赖。所有场景都有一个spring-boot-starter依赖。
以web场景器为例:Tomcat、springMVC常用组件:例如dispatcherServlet,viewResolver、web常见功能:例如字符编码问题characterEncodingFilter
包扫描:默认扫描主程序所在的包及其子包,可通过@SpringBootApplication(scanBasePackages = “xxx”)修改。
配置信息:各种配置都有默认值,且各个配置都会映射到对应java类的属性上,而这些类会注入到容器中。可通过application.properties修改。
按需加载配置:只有引入的场景才开启配置。这些自动配置由spring-boot-autoconfigure依赖实现。
com/zone/conf/MyConfig.java
⚡️只有在容器中的组件,才能拥有sb提供的功能
@Configuration(proxyBeanMethods = true)
@EnableConfigurationProperties(MyProperties.class)
public class MyConfig {
@Bean
public Lei lei() {
return new Lei("bl");//注入ioc容器
}
}
@Configuration 声明该类为配置类,等价配置文件(beans.xml)
属性:proxyBeanMethods,是否代理@Bean方法。如果为true,则配置类会被代理,直接从容器中获取实例(等价getBean),也就是多次调用lei()方法获得的实例是一样的。若为false, 则不代理,每次调用返回新实例。
模式:Full,Lite,对应proxyBeanMethods为true和false的时候
使用:组件之间无依赖关系,使用Lite模式,能减少判断,加速容器启动过程。反之使用Full模式。
@Bean/@Component() 给容器添加组件,前者作用于方法,后者作用于类,组件名字为方法名, 可通过value/name进行修改
@Import({Lei.class}) 给容器添加无参构造器的组件,作用于配置类,组件名字为全类名com.zone.pojo.Lei
@ComponentScan() 包扫描,如果没有指定扫描路径,默认扫描当前类所在的包下的路径。
@Conditional 、ConditionalOnBean、ConditionalOnMissingBean
条件装配,可用于类或方法,符合该条件时,组件才能注入容器;用属性name指定组件名;
@ImportResource(“classpath:fileName.xml”):引入xml配置文件,实现组件注入,回到原生的spring。
将组件的属性和配置文件对应起来,然后就只需通过修改配置文件,就可以实现不同效果。
1.@ConfigurationProperties 开启配置绑定 + @Component注入容器
@Component
@ConfigurationProperties(prefix = "zone.property")
@Data//需要提供set方法
@AllArgsConstructor
@NoArgsConstructor
public class MyProperties {
String username;
String password;
}
2.对于第三方组件,由于无法添加@Component,可在配置类中添加@EnableConfigurationProperties(第三方类.class)
配置文件application.properties:
zone.property.username=lonk
zone.property.password=zone
@Component
public class WxComponent {
@Value("${wx.open.app_id}")
private String appId;
@Value("${wx.open.app_secret}")
private String appSecret;
@Value("${wx.open.redirect_url}")
private String redirectUrl;
自己编写的绑定类,在idea配置文件修改时一般没有提示,绑定类的顶部有一句提示:Spring Boot Configuration Annotation Processor not found in classpath
Configuration Metadata (spring.io)
查看文档发现需要引入依赖:configuration-processor
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-configuration-processorartifactId>
<optional>trueoptional>
dependency>
导出jar包时,无需添加该依赖,在打包插件下面配置移除
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-configuration-processorartifactId>
exclude>
excludes>
configuration>
plugin>
plugins>
build>
@SpringBootApplication注解:声明这是一个sb应用,该类为主程序类
@SpringBootApplication
public class BootApplication {
public static void main(String[] args) {
//启动,该函数的返回ioc容器
ConfigurableApplicationContext context = SpringApplication.run(BootApplication.class,args);
}
}
//查看组件getBeanDefinitionNames() 获取组件getBean() 判断组件是否存在containsBean()
@SpringBootApplication注解:是一个复合注解,声明这是一个sb应用
底层都是通过Spring注解实现。
@SpringBootApplication:
@SpringBootConfiguration
@EnaleAutoConfiguration(自动装配原理)
@AutoConfigurationPackage ==> @Import(AutoConfigurationPackages.Registrar.class)
用Registrar将指定包下(主配置类所在的包)的所有组件注入容器
@Import({AutoConfigurationImportSelector.class})
向容器注入组件(xxxAutoConfiguration)。组件来自spring-boot-autoconfigure-2.3.7.RELEASE.jar下的META-INF/spring.factories文件,即通过加载文件注入组件。但组件会根据@Conditional按需配置。
其它组件的注入由这些配置类实现:如DispatcherServlet在DispatcherServletAutoConfiguration里面实现容器的注入。
在启动类中,通过SpringApplication的静态run方法进行SpringApplication的实例化,然后实例化对象调用另一个run方法,创建应用监听器SpringApplicationRunListeners开始监听,接着加载SpringBoot配置环境(ConfigurableEnvironment),然后把配置环境(Environment)加入监听对象中,然后加载应用上下文(ConfigurableApplicationContext),当做run方法的返回对象,最后创建Spring容器,refreshContext(context),实现starter自动化配置和bean的实例化等工作。
简化:在启动类中,通过SpringApplication的静态run方法进行SpringApplication的实例化,然后实例化对象调用另一个run方法实现项目的初始化和启动。
sb默认会在底层配置后好组件,但用户的配置优先。
例如:xxxAutoConfiguration帮你配好了字符过滤器,你也可以在自定义配置类中通过@Bean向容器注入。但是一般的做法是直接去修改application.propeties来改变组件属性对应的值。例如编码格式等等
public class HttpEncodingAutoConfiguration {...
@Bean
@ConditionalOnMissingBean
public CharacterEncodingFilter characterEncodingFilter() {
CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
....
return filter;
}
}
xxxAutoCongiguration – 注入组件 – xxxProperties有组件需要的值(跟组件配置绑定) – 我们通过application.properties配置,从而修改xxxProperties里面的默认值。
引入场景依赖
Idea源码分析自动配置了那些东西
配置文件添加debug=true,开启自动配置报告,其中Negative(不生效)/Positive(生效)
按需修改配置
参照文档修改配置文件
自定义组件@Bean…
自定义器 xxxCustomizer
不过一定要注意,自动装配一定要提供set方法,使用lombok的缺点就是你会忽视,有时候去掉一个注解可能就会报错。
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-devtoolsartifactId>
<optional>trueoptional>
dependency>
1.手动重新build项目,热部署生效
配置自动生效
日志的打印可以使用@Slf4j
默认控制台输出设置
logging.level.root=info
使用logback实现控制台和文件的输出
添加logback-spring.xml到resources目录下,实现日志格式化的输出到控制台、文件。
@ControllerAdvice//声明统一异常处理类
@Slf4j
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)//处理那类异常,可自定义异常
@ResponseBody
public ResUtil error(Exception e){
e.printStackTrace();
return ResUtil.error().message("Exception");
}
一种配置文件,适合以数据为中心的配置文件。跟json很像
语法:
⚡️classpath和classpath*(都是类路径下(Resource),区别在于是否包括jar包也查找)
sboot
默认目录:位于类路径下的且名字为/static /public /resources /META-INF/resources
[ "classpath:/META-INF/resources/","classpath:/resources/", "classpath:/static/", "classpath:/public/" ];
修改默认静态资源路径:
spring:
resources:
static-locations: ["classpath:/path/"]
访问:项目根路径+/静态资源名
原理:默认无前缀
spring:
mvc:
static-path-pattern: /**
添加访问前缀:
spring:
mvc:
static-path-pattern: /zone/**
实现欢迎页面(首页)和网站导航小图标
将index.html和**命名为favicon的icon图标(favicon.icon)**放在静态资源目录下。配置访问前缀会影响该功能。
*webjar:
web库(如jQuery,BootStrap)的jar包,有自己对应的静态目录(/META-INF/resources/),将jar包导入项目后,通过以上规则即可访问静态资源。WebJars - Web Libraries in Jars
依赖
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-jdbcartifactId>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
dependency>
配置
# 8.0.26
spring:
datasource:
url: jdbc:mysql://47.92.48.147:3306/review
username: zone
password: zone
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc:
template:
query-timeout: 3
测试:/Users/zone/IdeaProjects/boot3/src/main/java/com/zone/boot3/jdbc/JdbcController.java
源码位置:
org\springframework\boot\autoconfigure\jdbc
DataSourceAutoConfiguration 自动配置数据源
@Configuration(proxyBeanMethods = false)
@Conditional(PooledDataSourceCondition.class)
@ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
@Import({ DataSourceConfiguration.Hikari.class, DataSourceConfiguration.Tomcat.class,
DataSourceConfiguration.Dbcp2.class, DataSourceConfiguration.Generic.class,
DataSourceJmxConfiguration.class })
protected static class PooledDataSourceConfiguration {
}
默认数据源是HikariDataSource,配置绑定DataSourceProperties,没有其它数据库连接池,才配置HikariDataSource
修改配置 spring.datasource
JdbcTemplateAutoConfiguration 自动配置JdbcTemplate 配置绑定JdbcProperties
数据库操作 jdbcTemplate
修改配置 spring.jdbc
DataSourceTransactionManagerAutoConfiguration 事务管理器配置
JndiDataSourceAutoConfiguration jndi的配置
XADataSourceAutoConfiguration 分布式事务配置
中文文档 · alibaba/druid Wiki (github.com)
一种数据库连接池,提供监控和扩展功能。
依赖
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.2.8version>
dependency>
配置数据源
@Configuration
public class DruidDataSourceConfig {
//1.配置绑定,这样就可以直接读取配置文件配置,去除set步骤
@ConfigurationProperties("spring.datasource")
@Bean
public DruidDataSource druidDataSource(){
DruidDataSource druidDataSource = new DruidDataSource();
//2.sp通set方法配置参数
//3.开启监控,SQL防火墙功能,下面会用到
source.setFilters("stat,wall");
return druidDataSource;
}
}
测试:/Users/zone/IdeaProjects/boot3/src/main/java/com/zone/boot3/druid/DruidController.java
配置sql监控功能(数据源、sql、防火墙的监控等)
内置StatViewServlet提供监控信息页面
@Bean
public ServletRegistrationBean<StatViewServlet> servletServletRegistrationBean(){
StatViewServlet svs = new StatViewServlet();
ServletRegistrationBean<StatViewServlet> ssrb = new ServletRegistrationBean<>(svs,"/druid/*");
//可添加登录验证
ssrb.addInitParameter("loginUsername","zone");
ssrb.addInitParameter("loginPassword","zone");
return ssrb;
}
web关联的监控配置(URI监控等)
WebStatFilter用于采集web-jdbc关联监控的数据(请求次数等的监控)
@Bean
public FilterRegistrationBean<WebStatFilter> filterFilterRegistrationBean(){
WebStatFilter webStatFilter = new WebStatFilter();
FilterRegistrationBean<WebStatFilter> frb = new FilterRegistrationBean<>(webStatFilter);
//排除某些路径
frb.addInitParameter("exclusions","*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
//拦截路径
frb.setUrlPatterns(Arrays.asList("/*"));
return frb;
}
测试:localhost:8080/druid
druid-spring-boot-starter
依赖
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druid-spring-boot-starterartifactId>
<version>1.1.17version>
dependency>
具体配置,数据源的配置略,也可参看链接
# 8.0.26
spring:
datasource:
url: jdbc:mysql://47.92.48.147:3306/review
username: zone
password: zone
driver-class-name: com.mysql.cj.jdbc.Driver
druid:
# 开启监控和防火墙
filters: stat,wall
# 具体配置
filter:
stat:
enabled: true
slow-sql-millis: 1000 #规定慢sql的执行时间
log-slow-sql: true #记录慢sql
wall:
enabled: true
config:
drop-table-allow: false #不允许删除表
# 配置WebStatFilter和WebStatFilter
web-stat-filter:
enabled: true
# url-pattern和exclusions不配置也会默认配置
stat-view-servlet:
enabled: true
url-pattern: /druid/*
login-username: zone
login-password: zone
reset-enable: false
# 配置spring监控
aop-patterns: com.zone.boot4.*
源码
DruidSpringAopConfiguration.class 监控springbean
DruidStatViewServletConfiguration.class 监控页配置
DruidWebStatFilterConfiguration.class web监控配置
DruidFilterConfiguration.class filter配置
都有其对应的配置绑定
测试:参加整合mybatis
boot4
1.依赖
<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-starterartifactId>
<version>2.2.2version>
dependency>
2.类的解析
MybatisAutoConfiguration >> MybatisProperties >> prefix = “mybatis”
MybatisProperties类的configuration属性,用于取代mybatis主配置文件 >> mybatis.configuration.
private Configuration configuration;
3.mapper和mapper.xml的编写不变
4.配置
mybatis:
#类型别名
type-aliases-package: com.zone.boot4.pojo
configuration:
map-underscore-to-camel-case: true
#config-location: mybatis/mybatis-config.xml
mapper-locations: classpath:xml/*.xml; #对应resource文件夹下
由于configuration代表主配置类,所以不能同时配上config-location(主配置文件),需二选一。
java.lang.IllegalStateException:
Property 'configuration' and 'configLocation' can not specified with together
apper-locations能够定位resource目录下的xml文件,编写mapper.xml文件需要放在该目录下。
无法放在java目录下,即便在pom文件中build标签配置资源导出,sb的估计是固定了
5.@Mapper
我们需要为每个Mapper类添加@Mapper注解。或者在配置类上添加全局包扫描@MapperScan(mapper类所在的包)
否则会出现找不到该bean的错误
Field mapper in com.zone.boot4.crud.DruidController required a bean of type 'com.zone.boot4.mapper.DruidMapper' that could not be found.
6.使用
复杂的sql可以使用xml,简单的可直接用注解。下面以主键回填为例
xml
<insert id="insertCity" parameterType="city" useGeneratedKeys="true" keyProperty="id">
insert into city (NAME,state,country) values (#{name},#{state},#{country});
insert>
注解
@Insert("insert into city (NAME,state,country) values (#{name},#{state},#{country});")
@Options(useGeneratedKeys = true, keyProperty = "id")
void addCity(City city);
Spring Boot Actuator: Production-ready Features
指标监控
引入场景:
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
访问:http://localhost:8080/actuator/监控端点
Endpoints常用端点:beans,conditions,health,info,metrics,loggers
配置:
#以web方式暴露端点信息,sb2大部分端点被屏蔽
management.endpoints.web.exposure.include='*'
management.endpoint.headlth.show-details=always
定制Endpoint
Health: 监控状况,通过继承AbstractHealthIndicator实现
@Component
public class MyHealthIndicator extends AbstractHealthIndicator {
@Override
protected void doHealthCheck(Health.Builder builder) throws Exception {
HashMap<String, Object> map = new HashMap<>();
//满足条件则健康
if (1 + 1 == 2){
builder.status(Status.UP);
map.put("msg","...");
map.put("others","...");
} else{
builder.status(Status.DOWN);
map.put("err","...");
}
builder.withDetail("key","value")
.withDetails(map);
}
}
Info: 项目信息,实现InfoContributor
@Component
public class MyInfoContributor implements InfoContributor {
@Override
public void contribute(Info.Builder builder) {
builder.withDetail("名称","tfboot")
.withDetail("技术","sb,mybatis,lombok");
}
}
也可在yaml中直接配置
info:
test: 33
soga: 34
metrics 监控指标
例如某个方法调用次数的统计
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
@RestController
public class CityController {
@Autowired
CityService cityService;
Counter counter;
//构造器传入
public CityController(MeterRegistry meterRegistry) {
counter = meterRegistry.counter("cityController.getAllCity.count");
}
@RequestMapping("/select")
public List<City> getAllCity(){
counter.increment();//计数
return cityService.getAllCity();
}
}
//访问:http://localhost:8080/actuator/metrics/cityController.getAllCity.count
自定义端点
@Component
@Endpoint(id = "container")
public class DockerEndpoint {
@ReadOperation
public Map getDockerInfo(){
return Collections.singletonMap("info","docker started...");
}
@WriteOperation
private void restartDocker(){
System.out.println("docker restarted....");
}
}
可视化
Spring Boot Admin Reference Guide (codecentric.github.io)
需要两个项目,注意端口不能相同
标注:依赖高版本有问题
服务端项目
导入依赖,启动类添加@EnableAdminServer注解
<dependency>
<groupId>de.codecentricgroupId>
<artifactId>spring-boot-admin-starter-serverartifactId>
<version>2.3.1version>
dependency>
配置:
server.port=8888
客户端项目
导入依赖
<dependency>
<groupId>de.codecentricgroupId>
<artifactId>spring-boot-admin-starter-clientartifactId>
<version>2.3.1version>
dependency>
配置
server.port=8080
#注册服务器地址
spring.boot.admin.client.url=http://localhost:8888
#...监控指标配置
访问:http://localhost:8888