SpringBoot笔记
一、SpringBoot 介绍
1.1、SpringBoot简介
SpringBoot 是一个快速开发的框架, 封装了Maven常用依赖、能够快速的整合第三方框架;简化XML配置,全部采用注解形式,内置Tomcat、Jetty、Undertow,帮助开发者能够实现快速开发,SpringBoot的Web组件 默认集成的是SpringMVC框架。
SpringBoot原理介绍:
1. 能够帮助开发者实现快速整合第三方框架 (原理:Maven依赖封装)
2. 去除xml配置 完全采用注解化 (原理:Spring体系中内置注解方式)
3. 无需外部Tomcat、内部实现服务器(原理:Java语言支持创建Tomcat服务器)
1.2、SpringBoot和SpringMVC的区别
SpringBoot 是一个快速开发的框架,能够快速的整合第三方框架,简化XML配置,全部采用注解形式,内置Tomcat容器,帮助开发者能够实现快速开发,SpringBoot的Web组件 默认集成的是SpringMVC框架。
SpringMVC是控制层。
1.3、SpringBoot和SpringColud区别
SpringBoot 是一个快速开发的框架,能够快速的整合第三方框架,简化XML配置,全部采用注解形式,内置Tomcat容器,帮助开发者能够实现快速开发,SpringBoot的Web组件 默认集成的是SpringMVC框架。
SpringCloud依赖与SpringBoot组件,使用SpringMVC编写Http协议接口,同时SpringCloud是一套完整的微服务解决框架。
二、第一个SpringBoot程序
需求:
编写一个http接口,实现访问/hello,在页面上输出hello SpringBoot字符串?
实现:
2.1、创建Maven jar项目
2.2、在pom.xml文件中给项目添加父工程
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-parent</artifactId><version>2.3.8.RELEASE</version></parent>
2.3、在项目的pom.xml文件中导入依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
2.4、两个依赖的作用
1.spring-boot-starter-parent作用
在pom.xml中引入spring-boot-start-parent,spring官方的解释叫什么stater poms,它可以提供dependency management,也就是说依赖管理。
2.spring-boot-starter-web作用
springweb 核心组件
2.5、编写启动类
/**
* 项目的启动类
*/@SpringBootApplicationpublicclassDemoApplication{publicstaticvoidmain(String[] args){SpringApplication.run(DemoApplication.class,args);}}
2.6、在启动类所在的包或者子包下创建controller包
2.7、创建DemoController
@ControllerpublicclassDemoController{@RequestMapping("/hello")@ResponseBodypublicStringhello(){return"Hello SpringBoot!";}}
2.8、启动、测试
2.9、部署SpringBoot程序
2.9.1 在pom.xml文件中添加打包插件
<build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
2.9.2 在命令行窗口执行mvn package
2.9.3 进入jar所在的目录–>cmd -->java -jar xxxx.jar
三、SpringBoot探究
3.1、启动类
/**
* @SpringBootApplication 表示他是一个SpringBoot程序
*/@SpringBootApplicationpublicclassDemoApplication{publicstaticvoidmain(String[] args){//表示运行一个被@SpringBootApplication注解标注的Spring程序SpringApplication.run(DemoApplication.class, args);}}
@SpringBootApplication 他是一个组合注解
@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan(
excludeFilters={@Filter(
type=FilterType.CUSTOM,
classes={TypeExcludeFilter.class}),@Filter(
type=FilterType.CUSTOM,
classes={AutoConfigurationExcludeFilter.class})})public@interfaceSpringBootApplication{
@SpringBootConfiguration :SpringBoot配置
@Configuration 使用这个注解标注的类是一个配置类 作用相当于我们之前学习的xxxx.xml
@EnableAutoConfiguration :启动SpringBoot自动配置
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
1. @AutoConfigurationPackage:自动配置包
@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@Import({Registrar.class})public@interfaceAutoConfigurationPackage{String[]basePackages()default{};Class<?>[]basePackageClasses()default{};}
@Import({Register.class})
//注册bean的定义信息 到spring的IOC容器publicvoidregisterBeanDefinitions(AnnotationMetadata metadata,BeanDefinitionRegistry registry){AutoConfigurationPackages.register(registry,(String[])(newAutoConfigurationPackages.PackageImports(metadata)).getPackageNames().toArray(newString[0]));}
选中(new AutoConfigurationPackages.PackageImports(metadata)).getPackageNames() -->右键 -->Evaluate Expression 得出的结果为 项目启动类所在的包 ,也就是说和启动类在同一个包以及子包下定义的类会被注册到Spring的IOC容器中,也就解释了我们没有配置扫描某个包,却能注册bean到SpringIOC容器中
<font color="red">结论:我们创建的包必须是和启动类在同一个包或者子包内</font>
2. @Import({AutoConfigurationImportSelector.class}) 导入自动配置导入选择器
在这个AutoConfigurationImportSelector中有一个方法
```java
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return NO_IMPORTS;
} else {
AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
}
在这个方法中调用了getAutoConfigurationEntry(annotationMetadata)
```java
protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
} else {
AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
configurations = this.removeDuplicates(configurations);
Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
this.checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = this.getConfigurationClassFilter().filter(configurations);
this.fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
}
}
调试List configurations 或者的结果是127个xxxAutoConfiguration自动配置类,这些配置类在META-INF/spring.factories定义的
#### 3.2、SpringBoot配置文件
1. springboot的配置文件有2种:
yaml application.yml
properties application.properties
文件的名称必须叫以上2种,不能叫其他的
2. 配置文件优先级
properties的优先级高于yml
3. yaml的语法
1. yaml的基本语法:
使用缩进表示层级关系,缩进时不允许使用Tab键,只允许使用空格(例如:k:(空格) v),缩进的空格数目不重要,但是相同层级的元素左对齐即可,大小写敏感
2. YAML 支持的三种数据结构
- 字面量:单个的、不可再分的值
使用k: v 直接写
字符串类型的v默认不用双引号或者单引号;
“”:双引号;不会转义字符串里面的特殊字符;特殊字符会作为本身想表示的意思
eg: name: "zhangsan \n lisi" 输出:zhangsan 换行 lisi
‘’:单引号;会转义特殊字符,特殊字符最终只是一个普通的字符串数据
eg: name: "zhangsan \n lisi" 输出:zhangsan \n lisi
- 对象:键值对的集合
k: v 在下一行来写对象的属性和值的关系;注意缩进
1.还是k: v的方式
eg:
friends:
lastName: zhangsan
age: age
2.行内写法:
eg:
friends: {lastName: zhangsan,age: 18}
- 数组
一组按次序排列的值
1.用-值表示数组中的一个元素
eg:
pets:
-cat
-dog
-pig
2.行内写法:
pets: “cat,dog,pig”
4. properties的编码配置

#### 3.3、SpringBoot配置文件中属性的读取
在需要读取yml文件中属性值的类添加2个注解@ConfigurationProperties(prefix="前缀")、@Configuration/@Component
```java
/**
* @author lrg on 2021/7/23
* @since 1.0.0
* @ConfigurationProperties(prefix = "user") 读取配置文件中前缀为user的数据,
* 然后就可以按照属性名称设置属性值,但是使用这个注解标注的类必须是一个组件或者是能扫描到这个类,
* 或者是一个配置类,也就是在类上添加一个@Configuration注解
*/
@Data
@Component
@ConfigurationProperties(prefix = "person")
@ToString
public class User {
private String name;
private String email;
private String address;
3.4、SpringBoot测试
添加依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>
在测试类上添加注解
@RunWith(SpringRunner.class)
@SpringBootTest
@RunWith(SpringRunner.class)@SpringBootTestclassSpringboot02ApplicationTests{@AutowiredprivateUser user;@TestvoidcontextLoads(){System.out.println(user.toString());}}
3.5、常用注解
@propertysource 用于引入指定的属性文件
案例:
1. 在resources下创建一个user.properties属性文件
在属性文件中添加如下内容
person.name=zhangsan person.email=123456@qq.com person.address=北京市 person.dog.name=旺财 person.dog.strain=中华田园犬 person.aihao=[kanshu,xiezi,qiaodaima]
创建实体类User.java,如下:
@Data@ToString@Component@PropertySource("classpath:user.properties")//导入属性文件@ConfigurationProperties(prefix="person")publicclassUser{privateString name;privateString email;privateString address;privateDog dog;privateList<String> aihao;}
- 编写测试类测试
@ImportResource 导入Spring的配置文件
@Bean 配置Spring IOC中的Bean
案例:
@ConfigurationpublicclassDruidConfiguration{/*
* 类似于在Spring的配置文件中做了如下配置
* <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
* </bean>
*/@Bean@ConfigurationProperties(prefix="spring.datasource")publicDataSourcedataSource(){returnnewDruidDataSource();}
3.6、banner设置
默认banner:
步骤:
找到自己喜欢的banner
地址:https://www.bootschool.net/ascii
下载banner.txt
默认方式是将banner.txt放在resources下
不是默认方式就需要在SpringBoot的配置文件中去进行配置
例如:我将banner.txt文件放在resources/banner.txt,就需要在SpringBoot的配置文件中去做如下的配置
#设置bannerspring:banner:location: banner/banner.txt
3.7、Profile
Profile是Spring对不同环境提供不同配置功能的支持,可以通过激活、指定参数等方式快速切换环境
- 多profile文件形式
-格式:application-{profile}.properties:
application-dev.properties、application-prod.properties
多profile文档模式:在主配置文件中指定多个环境
例如:
spring:profiles:active: test#指定使用的时哪一个环境---#开发环境devspring:profiles: devserver:port:8082---#测试环境spring:profiles: testserver:port:8083
激活方式:
-配置文件 spring.profiles.active=dev
-命令行 --spring.profiles.active=dev
-jvm参数 -Dspring.profiles.active=dev
注意:第二种一般时项目已经写好并且已经打包好,在运行jar文件的时候去指定使用哪一个配置文件如: java -jar springboot-02-0.0.1-SNAPSHOT.jar --spring.profiles.active=test
3.8、配置文件的加载位置
spring boot启动会扫描以下位置的application.properties或者application.yml文件作为Spring boot的默认配置文件
-file:./config/
-file:./
-classpath:/config/
-classpath:/
以上是按照优先级从高到低的顺序,所有位置的文件都会被加载,高优先级配置内容会覆盖低优先级配置内容。 互补配置
我们也可以通过配置spring.config.location来改变默认配置。项目打包好以后,我们可以使用命令行参数的形式,启动项目的时候来指定配置文件的新位置;指定配置文件和默认加载的这些配置文件共同起作用形成互补配置;
java -jar xxx.jar -Dspring.config.location=E:/application.yml
四、Web开发
4.1、静态资源访问
在我们开发Web应用的时候,需要引用大量的js、css、图片等静态资源。
默认配置
Spring Boot默认提供静态资源目录位置需置于classpath下,目录名需符合如下规则:
/static
/public
/resources
/META-INF/resources
举例:我们可以在src/main/resources/目录下创建static,在该位置放置一个图片文件。启动程序后,尝试访问http://localhost:8080/D.jpg。如能显示图片,配置成功。
4.2、渲染Web页面
通过@RestController来处理请求,所以返回的内容为json对象。那么如果需要渲染html页面的时候,要如何实现呢?
模板引擎
在动态HTML实现上Spring Boot依然可以完美胜任,并且提供了多种模板引擎的默认配置支持,所以在推荐的模板引擎下,我们可以很快的上手开发动态网站。
Spring Boot提供了默认配置的模板引擎主要有以下几种:
Thymeleaf
FreeMarker
Velocity
Groovy
Mustache
Spring Boot建议使用这些模板引擎,避免使用JSP,若一定要使用JSP将无法实现Spring Boot的多种特性。
当你使用上述模板引擎中的任何一个,它们默认的模板配置路径为:src/main/resources/templates。当然也可以修改这个路径,具体如何修改,可在后续各模板引擎的配置属性中查询并修改。
4.3、全局捕获异常
@ExceptionHandler 表示拦截异常
@ControllerAdvice 是 controller 的一个辅助类,最常用的就是作为全局异常处理的切面类
@ControllerAdvice 可以指定扫描范围
@ControllerAdvice 约定了几种可行的返回值,如果是直接返回 model 类的话,需要使用 @ResponseBody 进行 json 转换
返回 String,表示跳到某个 view
返回 modelAndView
返回 model + @ResponseBody
@ControllerAdvicepublicclassMayiktExceptionHandler{/**
* 拦截运行异常出现的错误~~~
*
* @return
*/@ExceptionHandler(RuntimeException.class)@ResponseBodypublicMap<Object,Object>exceptionHandler(){Map<Object,Object> map=newHashMap<>();
map.put("error","500");
map.put("msg","系统出现错误~");return map;}}
五、数据访问
5.1、JdbcTemplate操作数据库
在pom.xml文件中添加依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId> 这里要加MySQL的版本号</dependency>
在SpringBoot的配置文件application.yml文件中配置数据源
spring:#配置数据源datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/smbms?serverTimezone=GMT%2B8&useSSL=trueusername: rootpassword: root
springboot默认给我们添加的数据源是:
com.zaxxer.hikari.HikariDataSource//这个数据源号称是效率最高的数据源
另外还提供了很多的数据源:如下
org.apache.tomcat.jdbc.pool.DataSource org.apache.commons.dbcp2.BasicDataSource
如果这些数据源我们不想要,还可以通过如下方法自定义数据源
@Configuration(proxyBeanMethods=false)@ConditionalOnMissingBean(DataSource.class)@ConditionalOnProperty(name="spring.datasource.type")staticclassGeneric{@BeanDataSourcedataSource(DataSourceProperties properties){return properties.initializeDataSourceBuilder().build();}}
可以使用JdbcTemplate来操作数据库了
@ControllerpublicclassJdbcController{@AutowiredprivateJdbcTemplate template;@RequestMapping("/index")@ResponseBodypublicList<Map<String,Object>>index(){List<Map<String,Object>> maps= template.queryForList("select * from smbms_user");return maps;}}
4. 访问测试
5.2、整合Druid
在pom.xml文件中添加如下依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--导入阿里巴巴数据源的依赖--><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.2</version></dependency>
在配置文件application.yml文件中添加如下依赖
#以下配置是发送电子邮件的配置spring:#以下是数据源的配置datasource:url: jdbc:mysql://192.168.1.223:3306/itrip_db? useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8#注意修改driver-class-name: com.mysql.cj.jdbc.Driverusername: root#注意修改password: root#注意修改type: com.alibaba.druid.pool.DruidDataSource#指定数据源的类型#以下是alibaba数据源的配置initialSize:5#初始化大小minIdle:5#最小连接数maxActive:20#最大连接数maxWait:60000#获取连接等待超时时间timeBetweenEvictionRunsMillis:60000#间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒minEvictableIdleTimeMillis:300000#一个连接在池中最小生存的时间,单位是毫秒validationQuery: SELECT 1 FROM DUALtestWhileIdle:truetestOnBorrow:falsetestOnReturn:falsepoolPreparedStatements:true# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙filters: stat,wall,slf4jmaxPoolPreparedStatementPerConnectionSize:20useGlobalDataSourceStat:trueconnectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
编写Druid的配置类
/** * DruidDataSource配置类 * */@ConfigurationpublicclassDruidConfiguration{/* * 类似于在Spring的配置文件中做了如下配置 * <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> * </bean> */@Bean@ConfigurationProperties(prefix="spring.datasource")publicDataSourcedataSource(){returnnewDruidDataSource();}//配置Druid的监控//1、配置一个管理后台的Servlet//访问的地址为:http://ip:port/上下文/druid@BeanpublicServletRegistrationBeanstatViewServlet(){ServletRegistrationBean bean=newServletRegistrationBean(newStatViewServlet(),"/druid/*");Map<String,String> initParams=newHashMap<>(); initParams.put("loginUsername","admin"); initParams.put("loginPassword","admin"); initParams.put("allow","");//配置允许哪一个IP地址访问 默认就是允许所有访问 initParams.put("deny","192.168.15.21");/*拒绝后面的这个IP地址访问*/ bean.setInitParameters(initParams);return bean;}
//2、配置一个web监控的filter@BeanpublicFilterRegistrationBeanwebStatFilter(){FilterRegistrationBean bean=newFilterRegistrationBean();
bean.setFilter(newWebStatFilter());Map<String,String> initParams=newHashMap<>();//设置不拦截的路径
initParams.put("exclusions","*.js,*.css,/druid/*");
bean.setInitParameters(initParams);//设置拦截的路径
bean.setUrlPatterns(Arrays.asList(