SpringBoot整合:Druid、MyBatis、MyBatis-Plus、多数据源、knife4j、日志、Redis,Redis的Java操作工具类、封装发送电子邮件等等

2022-06-17 14:45:16

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的编码配置

   ![](\img\properties.jpg)

#### 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测试

  1. 添加依赖

    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>
  2. 在测试类上添加注解

    @RunWith(SpringRunner.class)

    @SpringBootTest

    @RunWith(SpringRunner.class)@SpringBootTestclassSpringboot02ApplicationTests{@AutowiredprivateUser user;@TestvoidcontextLoads(){System.out.println(user.toString());}}

3.5、常用注解

@propertysource 用于引入指定的属性文件

案例:

1. 在resources下创建一个user.properties属性文件

  1. 在属性文件中添加如下内容

    person.name=zhangsan
    person.email=123456@qq.com
    person.address=北京市
    person.dog.name=旺财
    person.dog.strain=中华田园犬
    person.aihao=[kanshu,xiezi,qiaodaima]
  2. 创建实体类User.java,如下:

    @Data@ToString@Component@PropertySource("classpath:user.properties")//导入属性文件@ConfigurationProperties(prefix="person")publicclassUser{privateString name;privateString email;privateString address;privateDog dog;privateList<String> aihao;}
    1. 编写测试类测试

@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:
在这里插入图片描述

步骤:

  1. 找到自己喜欢的banner

    地址:https://www.bootschool.net/ascii

    1. 下载banner.txt

    2. 默认方式是将banner.txt放在resources下

    3. 不是默认方式就需要在SpringBoot的配置文件中去进行配置

    例如:我将banner.txt文件放在resources/banner.txt,就需要在SpringBoot的配置文件中去做如下的配置

    #设置bannerspring:banner:location: banner/banner.txt

3.7、Profile

Profile是Spring对不同环境提供不同配置功能的支持,可以通过激活、指定参数等方式快速切换环境

  1. 多profile文件形式
    -格式:application-{profile}.properties:
  application-dev.properties、application-prod.properties
  1. 多profile文档模式:在主配置文件中指定多个环境

    例如:

    spring:profiles:active: test#指定使用的时哪一个环境---#开发环境devspring:profiles: devserver:port:8082---#测试环境spring:profiles: testserver:port:8083
  2. 激活方式:

    -配置文件 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操作数据库

  1. 在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>
  2. 在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();}}
  3. 可以使用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

  1. 在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>
  2. 在配置文件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
  3. 编写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(
  • 作者:李潘杜若
  • 原文链接:https://blog.csdn.net/weixin_49385823/article/details/119281763
    更新时间:2022-06-17 14:45:16