springboot学习

整个文档参考尚硅谷雷丰阳老师的springboot笔记进行编写

第一个springboot程序

1、编写maven

 <parent>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-parent</artifactId>
     <version>2.5.5</version>
</parent>

springboot的web依赖

 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-web</artifactId>
</dependency>

因为springboot简化了部署,所以可以直接通过jar包的方式启动项目,并且里面内置了tomcat的jar包

<!--指定打包方式-->
<packaging>jar</packaging>

<!--打包插件-->
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

2、编写主类(也叫主配置类)

名称自定,这里为MainApplication

@SpringBootApplication 注解告诉springboot这个是启动类

@SpringBootApplication = (默认属性)@Configuration + @EnableAutoConfiguration + @ComponentScan。

@SpringBootApplication
public class MainApplication {
    public static void main(String[] args) {
        //固定使用方式
        SpringApplication.run(MainApplication.class, args);
    }
}

3、编写控制层

这里是springmvc里面的知识了

@RestController
public class HelloController {

    @RequestMapping("/hello")
    public String hello() {
        return "你好 springboot";
    }
}

4、运行

springboot的启动成功以后不会像tomcat一样自动跳到浏览器,需要去浏览器手动输入地址,默认8080端口

运行主类

image-20211011001908393

image-20211011001928998

5、通过配置文件修改端口

springboot简化了很多配置,其中大部分配置都会在application.properties中进行书写,注意:这个配置文件的名称是固定的

springboot的配置大全在spring的官网:https://docs.spring.io/spring-boot/docs/current/reference/html/application-properties.html#application-properties

默认是 8080 我们修改为 8081

image-20211011002131381

运行测试

image-20211011002227395

6、打包成jar包并在控制台运行

使用maven的打包功能

jar包存放路径有输出出来

image-20211011002429690

找到并通过命令行运行:

记得通过命令行运行的时候把idea的服务给停了,不然会端口占用

image-20211011002549526

访问成功

image-20211011002721917

1、springboot 依赖管理

依赖管理    
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.4.RELEASE</version>
</parent>

这里的这个官方文档是直接写上去的,没有具体说明为什么,我在csdn上找到了一些相关的解释,具体怎么看可以再idea ctrl+鼠标左键点击进去查看详情。这个parent提供了以下特性:

  1. 默认使用Java 8
  2. 使用UTF-8编码
  3. 几乎声明了所有开发中常用的依赖的版本号,自动版本仲裁机制
  4. 识别过来资源过滤
  5. 识别插件的配置
  6. 能够识别application.properties和application.yml类型的文件,同时也能支持profile-specific类型的文件(如: application-foo.properties and

application-foo.yml,这个功能可以更好的配置不同生产环境下的配置文件)。

  1. maven把默认的占位符 $${…} 改为了 @..@

点击进去发现他的父类里面有一个:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-dependencies</artifactId>
    <version>2.3.4.RELEASE</version>
</parent>

image-20211011170147556

几乎声明了所有开发中常用的依赖的版本号

这就是springboot的自动版本仲裁机制

无需关注版本号,自动版本仲裁

1、引入依赖默认都可以不写版本
2、引入非版本仲裁的jar,要写版本号。

修改默认的版本号

1、查看spring-boot-dependencies里面规定当前依赖的版本 用的 key。
2、在当前项目里面重写配置
<properties>
    <mysql.version>5.1.43</mysql.version>
</properties>

2、自动配置

  • 自动配好SpringMVC
    • 引入SpringMVC全套组件
    • 自动配好SpringMVC常用功能
  • 自动配好Web常见功能,如:字符编码问题
    • SpringBoot帮我们配置好了所有web开发的常见场景
  • 默认的包结构
    • 主程序所在包及其下面的所有子包里面的组件都会被默认扫描进来
    • 无需以前的包扫描配置
    • 想要改变扫描路径,@SpringBootApplication(scanBasePackages="com.atguigu")
      • 或者@ComponentScan 指定扫描路径
@SpringBootApplication
等同于
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("com.atguigu.boot")

springboot 的 application.properties 文件是配置文件,自动配置机制根据这个文件进行配置,如:

#配置tomcat端口
server.port=8081
#配置文件上传限制大小
spring.servlet.multipart.max-file-size=10MB

这个机制的实现依赖于 spring-boot-autoconfigure 实现

特性:按需加载,用到了才会进行自动装配

3、容器装配

番外:查看 ioc里面注册的组件:

ApplicationContext run = SpringApplication.run(MainApplication.class, args);
for (String beanDefinitionName : run.getBeanDefinitionNames()) {
    System.out.println(beanDefinitionName);
}

3.1、组件添加

1、@Configuration

之前我们配置spring bean的时候都是使用的xml文件,现在以及后面我们都会使用java来完成配置功能

也就是 @Configuration 其实这个是spring里面的东西

测试的两个类

@Data
public class User {
    private String name;
    private Integer age;
}

@Data
public class Pet {
    private String name;
}

配置类

@Configuration
public class AppConfig {

    @Bean("user")
    public User getUser() {
        User user = new User();
        user.setAge(10);
        user.setName("名称");
        return user;
    }

    @Bean("pet")
    public Pet getPet(){
        Pet pet = new Pet();
        pet.setName("旺财");
        return pet;
    }
}

主类

@SpringBootApplication
public class MainApplication {
    public static void main(String[] args) {
        //这里获取的是 spring ioc的容器
        ApplicationContext run = SpringApplication.run(MainApplication.class, args);
           //之后我们的测试就直接在这里
    }
}

spring的bean默认是单例的

User user1 = run.getBean("user", User.class);
User user2 = run.getBean("user", User.class);
System.out.println("user1==user2 = " + (user1 == user2));

image-20211011213505089

结果为 true 可以看出单例模式 可以通过@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) 配置为多例,这里不做过多讲解,这里属于spring的知识点

如果我们主动的去获得User,看下会发生什么

//配置类本身也是组件
AppConfig bean = run.getBean(AppConfig.class);
User user1 = bean.getUser();
User user2 = bean.getUser();
System.out.println("(user1==user2) = " + (user1 == user2));

image-20211011214216052

可以看到结果为 true

这是因为当我们去调用方法的时候回先去找spring容器里面存不存在这个实例,存在则返回容器里面的实例,不存在则重新创建一个对象返回

影响这个操做的配置在注解 @Configuration 注解里面的 proxyBeanMethods 属性。

image-20211011222707711

可以看到 proxyBeanMethods 默认为 true

  • Full(proxyBeanMethods = true

    • 利用cglib代理增强,bean是单例的,@Bean方法调用生成实例时,如果已经存在这个bean,直接返回
    • 正因为被代理了,所以@Bean方法 不可以是private、不可以是final

image-20211011224001325

  • Lite(proxyBeanMethods = false)

    • 此时配置类不是代理类 每个@Bean方法被调用多少次返回的组件都是新创建
    • Spring 5.2.0+的版本,建议你的配置类均采用Lite模式去做,即显示设置proxyBeanMethods = falseSpring Boot在2.2.0版本(依赖于Spring 5.2.0)起就把它的所有的自动配置类的此属性改为了false,**即@Configuration(proxyBeanMethods = false)提高Spring启动速度
  • 存在依赖:当一个bean方法内调用另外一个bean方法获取实例时,称为存在依赖

     @Bean("user")
        public User getUser() {
            User user = new User();
            user.setAge(10);
            user.setName("名称");
            //这里存在依赖
            Pet pet = getPet();
            return user;
        }
    
        @Bean("pet")
        public Pet getPet(){
            Pet pet = new Pet();
            pet.setName("旺财");
            return pet;
        }
  • 最佳实战

    • 配置 类组件之间无依赖关系用Lite模式加速容器启动过程,减少判断
    • 配置类组件之间有依赖关系,方法会被调用得到之前单实例组件,用Full模式

2、@import

自动从类中的无参构造函数创建一个实例注册到 IOC 容器中

@Import所创建的实例在 IOC 容器中默认的id名为类的全限定名,如 User 类就是:

image-20211011230539759

可以看出参数是一个数组

示例:

@Import({User.class,Pet.class})
@Configuration(proxyBeanMethods = true)
public class AppConfig {
}
ApplicationContext run = SpringApplication.run(MainApplication.class, args);
User user = run.getBean("com.yqlzmzr.boot.pojo.User", User.class);
Pet pet = run.getBean("com.yqlzmzr.boot.pojo.Pet", Pet.class);
System.out.println("user = " + user);
System.out.println("pet = " + pet);

image-20211011230835479

因为默认调用无参构造函数,所以里面的值为 null,但是确实已经存在在spring的容器里面了。

个人认为使用场景:配置类中需要加载的 类不多,切无须有参初始化的情况下可以使用

<font color=red size=5>注意:</font>

@Import注解用来导入配置类或一些需要前置加载的类,其可以通过快速导入的方式实现把实例加入Spring的IOC容器中。

3、@Conditional

条件注解是Spring4提供的一种bean加载特性,主要用于控制配置类和bean初始化条件。在springBoot,springCloud一系列框架底层源码中,条件注解的使用到处可见。其实springboot的按需加载大部分是基于这个注解及其子注解实现的

查看其派生注解:

image-20211011233155029

查看注解源码,发现他可以使用在类或者方法上

image-20211011233239252

img

这里转载一个知乎里面的测试代码 https://zhuanlan.zhihu.com/p/141613945

首先定义一个实体类:

@Data
@AllArgsConstructor
public class Person {  

    private String name;
    private int age;
}

应为我们这里使用的是 @Conditional 注解,这个注解里面的参数要实现Condition接口。

我们可以自定义一个类实现Condition接口。

public class ConditionalDemo1 implements Condition {
    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        Environment environment = conditionContext.getEnvironment();
        String property = environment.getProperty("os.name");
        if(property.contains("Windows")){
            return true;
        }
        return false;
    }
}

接下来写一个配置类

@Configuration
public class AppConfig {

    @Bean("user")
    @Conditional({TestCondition.class})
    public User getUser() {
        User user = new User();
        user.setName("xingming");
        user.setAge(122);
        return user;
    }
}

测试类:

@SpringBootApplication
public class MainApplication {
    public static void main(String[] args) {
        ApplicationContext run = SpringApplication.run(MainApplication.class, args);
        User user = run.getBean("user", User.class);
        System.out.println("user = " + user);
    }
}

运行:

image-20211011235505243

因为我们当前在windows环境下,返回值为 true 执行 user bean的装载

接下来我通过idea模拟下linux的环境

image-20211011235731852

image-20211011235748192

我们再次运行代码:

image-20211011235812260

我们发现报错了,因为此时不是windows,所以 user bean 不会注入到spring容器中,所以不存在,则报错。

3.2 原生xml配置文件装配

如果执意还要使用xml来配置spring,可以通过这个注解达到引入的目的

示例:

xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <bean class="com.yqlzmzr.boot.pojo.User" id="user">
        <property name="name" value="姓名"/>
        <property name="age" value="123"/>
    </bean>
</beans>

配置类:

@Configuration
@ImportResource("classpath:beans.xml")
public class AppConfig {

}

测试类:

@SpringBootApplication
public class MainApplication {
    public static void main(String[] args) {
        ApplicationContext run = SpringApplication.run(MainApplication.class, args);
        User user = run.getBean("user", User.class);
        System.out.println("user = " + user);
    }
}

结果:

image-20211012000712544

装配成功!

3.3 配置绑定

先定义一个类

@Data
public class User {
    private String name;
    private Integer age;
}

application.properties里面书写配置

user1.name=BF
user1.age=19

1、@ConfigurationProperties

添加该注解,并配置 prefix ,prefix代表那个前缀,

这里要加Componentr让这个类加入到容器中,还有第二种方法,下面有说明

@Component
@Configurationproperties(prefix="user1")
@Data
public class User {
    private String name;
    private Integer age;
}

测试:

@SpringBootApplication
public class MainApplication {
    public static void main(String[] args) {
        ApplicationContext run = SpringApplication.run(MainApplication.class, args);
        User bean = run.getBean(User.class);
        System.out.println("bean.toString() = " + bean);
    }
}

结果:

image-20211012225933439

2、@EnableConfigurationProperties + @ConfigurationProperties

@EnableConfigurationProperties 这个要写在配置类

@Configuration
@EnableConfigurationProperties(User.class)
//开启  User的配置绑定功能
// 自动把这个User注册到容器中
public class AppConfig {

}
@ConfigurationProperties(prefix = "user1")
@Data
public class User {
    private String name;
    private Integer age;
}

4、自动配置原理入门

4.1、引导加载自动配置类

@SpringBootApplication

我们查看他的源码,发现他由:

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
    excludeFilters = {@Filter(
    type = FilterType.CUSTOM,
    classes = {TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {AutoConfigurationExcludeFilter.class}
)}
)

这三个主要注解组成,我们逐一查看

4.1.1、@SpringBootConfiguration

image-20211012231624477

我们发现它里面有个配置注解,所以这个注解没有深究的意义,可以简单的理解为就是一个@Configuration注解,表示当前类是一个配置类

这段话是网上找到的,不知道对不对:

@ SpringBootConfiguration只是Spring标准@Configuration批注的替代方法。 两者之间的唯一区别是@SpringBootConfiguration允许自动找到配置。

4.1.2、@ComponentScan

包扫描注解,spring的基础知识,这里不做过多的概述

这里放一些常用属性概述:

basePackages、value:指定扫描路径,如果为空则以@ComponentScan注解的类所在的包为基本的扫描路径
basePackageClasses:指定具体扫描的类
includeFilters:指定满足Filter条件的类
excludeFilters:指定排除Filter条件的类

includeFilters和excludeFilters 的FilterType可选:ANNOTATION=注解类型 默认、ASSIGNABLE_TYPE(指定固定类)、ASPECTJ(ASPECTJ类型)、REGEX(正则表达式)、CUSTOM(自定义类型),自定义的Filter需要实现TypeFilter接口

4.1.3 、@EnableAutoConfiguration

我们查看源码:

image-20211012232710092

发现了这两个主要的注解,我们分开解说:

1、 @AutoConfigurationPackage

查看源码

image-20211012232804690

我们发现,这就是个帮我们把AutoConfigurationPackages.Registrar导入容器的注解。

AutoConfigurationPackages.Registrar又做了什么呢,我们查看源码:

image-20211012232944529

其实这里帮我们普亮注册了一个组件。我们打个断点,debug试试

我们发现,这里的参数 metadata其实就是注解的原信息,保存了注解的位置啥啥的

image-20211012233234764

我们来看下他的这条语句:new PackageImports(metadata).getPackageNames().toArray(new String[0])

image-20211012233541185

我们发现他这里得出了我们的包名

由此我们得出,这是一个批量注册我们 得出的这个包 下面的组件的注解

@AutoConfigurationPackage:这个组合注解主要是@Import(AutoConfigurationPackages.Registrar.class),它通过将Registrar类导入到容器中,而Registrar类作用是扫描主配置类同级目录以及子包,并将相应的组件导入到springboot创建管理的容器中;

<font color=red>我认为这个的作用就是简而言之的扫描你自己写的组件,然后加入容器中</font>

2 、@Import(AutoConfigurationImportSelector.class)

这里有点看不懂了,想具体了解的可以看雷丰阳springboot2 第14集的内容

1、利用getAutoConfigurationEntry(annotationMetadata);给容器中批量导入一些组件

2、调用List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes)获取到所有需要导入到容器中的配置类

3、利用工厂加载 Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader);得到所有的组件

4、从META-INF/spring.factories位置来加载一个文件。 默认扫描我们当前系统里面所有META-INF/spring.factories位置的文件

spring-boot-autoconfigure-2.3.4.RELEASE.jar包里面也有META-INF/spring.factories

内容为:

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\
org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\
org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,\
org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,\
org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration,\
org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration,\
org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration,\
org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration,\
org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,\
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,\
org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration,\
org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\
org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\
org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration,\
org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\
org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration,\
org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\
org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration,\
org.springframework.boot.autoconfigure.netty.NettyAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration,\
org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration,\
org.springframework.boot.autoconfigure.r2dbc.R2dbcTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketRequesterAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketServerAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration,\
org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration,\
org.springframework.boot.autoconfigure.security.rsocket.RSocketSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyAutoConfiguration,\
org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\
org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.resource.reactive.ReactiveOAuth2ResourceServerAutoConfiguration,\
org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,\
org.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConfiguration,\
org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration,\
org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration,\
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration,\
org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration,\
org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.function.client.ClientHttpConnectorAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.reactive.WebSocketReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.client.WebServiceTemplateAutoConfiguration

@Import(AutoConfigurationImportSelector.class):它通过将AutoConfigurationImportSelector类导入到容器中,AutoConfigurationImportSelector类作用是通过selectImports方法执行的过程中,会使用内部工具类SpringFactoriesLoader,查找classpath上所有jar包中的META-INF/spring.factories进行加载,实现将配置类信息交给SpringFactory加载器进行一系列的容器创建过程

<font color=red>我认为这个的作用就是按需加载springboot的场景(功能)包的自动配置类,然后加入容器中</font>

4.2、按需开启自动配置项

虽然在加载的时候我们会把所有的场景类读取,但是我们因为条件注解的原因,只有条件达成了才会加载进spring容器,这就是所谓的按需加载

我们查看 spring-boot-autoconfigure-2.5.5.jar可以看到springboot的自动转配包为了实现按需加载使用了大量的条件注解

image-20211013002223203

4.3、研究底层之配置

我们以 spring-boot-autoconfigure-2.5.5.jar包下 org.springframework.boot.autoconfigure.cache 里面的 CacheAutoConfiguration 的配置。

查看源码:

image-20211013111906019

我们发现这里有用 EnableConfigurationProperties注解开启配置 CacheProperties 我们查看 CacheProperties 的源码:

image-20211013121738912

我们发现了@ConfigurationProperties 并且prefix ="spring.cache" 那就以为这我们可以再application.properties里面配置他的参数

我们发现这个前缀的前提下确实有很多配置属性:

image-20211013122320698

我们也能发现这里确实有对应的成员变量:

image-20211013122347672

由此我们可以确定,springboot是通过这种方式和配置文件绑定起来的,进行初始化配置的,而他们也是本身有默认值的,我们可以不配,默认用户配置优先级最高

总结(照搬老师的)

  • SpringBoot先加载所有的自动配置类 xxxxxAutoConfiguration
  • 每个自动配置类按照条件进行生效,默认都会绑定配置文件指定的值。xxxxProperties里面拿。xxxProperties和配置文件进行了绑定
  • 生效的配置类就会给容器中装配很多组件
  • 只要容器中有这些组件,相当于这些功能就有了
  • 定制化配置
    • 用户直接自己@Bean替换底层的组件
    • 用户去看这个组件是获取的配置文件什么值就去修改。

xxxxxAutoConfiguration ---> 组件 ---> xxxxProperties里面拿值 ----> application.properties

5、WEB

这下面使用的都是idea创建的springboot的模板,具体怎么使用百度

5.1 静态资源访问

5.1.1、静态资源目录

只要静态资源放在类路径下: /static or /public or /resources or /META-INF/resources,哪个都行

访问 : 当前项目根路径/ + 静态资源名

image-20211018002412630

image-20211018002510529

原理: 静态映射 /**

请求进来,先去找Controller看能不能处理。不能处理的所有请求又都交给静态资源处理器。静态资源也找不到则响应404页面

5.1.2、静态资源访问前缀

静态资源默认在根路径下,现在更改静态资源的访问的路径

这里的yaml文件的语法可以百度学习,不难

spring:
  mvc:
    static-path-pattern: /file/**

image-20211018002854453

image-20211018003054688

文件目录结构我是没有改的,相当于给静态资源文件的访问添加了 层级前缀。

当前项目 + static-path-pattern + 静态资源名 = 静态资源文件夹下找

5.1.3、静态资源路径

如果我们不想使用上面官方指定的那几个文件夹名字,我们可以自定义

<font color=red>注意:这个方法已经被官方遗弃,做个了解就可以了</font>

我们现在resources下自定义一个文件夹,并放入图片

image-20211018003937959

我们访问试一下:

image-20211018004019621

我们发现是访问不了的,此时我们通过配置文件添加我们的这个路径:

spring:
  mvc:
    static-path-pattern: /file/**

  resources:
    static-locations: [classpath:/wocao/]

重启服务,再试着访问一下:

image-20211018004139990

我们发现可以访问了。

5.2 请求参数处理

5.2.1 rest实现原理之表单形式

我们编写对应的Controller

@GetMapping("/user")
public String getUser(){
    return "get访问";
}
@PostMapping("/user")
public String postUser(){
    return "post访问";
}

@DeleteMapping("/user")
public String deleteUser(){
    return "delete访问";
}

@PutMapping ("/user")
public String putUser(){
    return "Put访问";
}

编写前端:

<form action="http://localhost:8080/user" method="post">
    <input type="submit" value="提交post">
</form>
<form action="http://localhost:8080/user" method="get">
    <input type="submit" value="提交get">
</form>
<form action="http://localhost:8080/user" method="delete">
    <input type="submit" value="提交delete">
</form>
<form action="http://localhost:8080/user" method="put">
    <input type="submit" value="提交put">
</for

我们发现get和post是正常的,但是delete和put都走了get,所以我们这样是肯定不对的

mvc在处理表单rest请求的时候因为from表单只有get,post请求,所以mvc提出了一个解决方案,是 hiddenMethodsFilter 过滤器,他在WebMvcAutoConfiguration中,我们查看一下源码

image-20211022104104623

我们确实在里面发现了 hiddenMethodsFilter 并且使用 @ConditionalOnMissingBean(HiddenHttpMethodFilter.class) 约束:当我们自己没有具体实现(也就是自己写configuration配置)时才执行他的默认配置。

通过 @ConditionalOnProperty(prefix = "spring.mvc.hiddenmethod.filter", name = "enabled")我们可以看出这个功能需要在配置文件中开启,默认值为false 不开启

我们现在配置文件里面配置一下这个功能开启。

image-20211022104759608

此时我们再试一下,发现还是不行,说明事情不止这么简单,我们深入的了解下OrderedHiddenHttpMethodFilter的源码,看他的具体实现

image-20211022104948973

我们发现这里面没有什么具体的实现,说明我们要去观察他的父类HiddenHttpMethodFilter,我们进入 HiddenHttpMethodFilter的源码,

我们具体看这个的实现

image-20211022105239192

我们可以看出 "POST".equals(request.getMethod())这里可以看出 delete put基于post 请求,所以我们的表单的method要改成 post:

<form action="http://localhost:8080/user" method="post">
    <input type="submit" value="提交delete">
</form>
<form action="http://localhost:8080/user" method="post">
    <input type="submit" value="提交put">
</form>

那怎么判断是delete还是put呢,我们往下分析

String paramValue = request.getParameter(this.methodParam);

我们看到这句话,我们去找下 this.methodParam ,发现值为:

image-20211022111147336

_method,所以我们的表单是不是应该带上这个属性,但是这个属性的值是什么呢,我们再往下分析

我们看到:

String method = paramValue.toUpperCase(Locale.ENGLISH);
if (ALLOWED_METHODS.contains(method))
...

这里的toUpperCase是转为大写,不是重点,我们往下看看到他有一个判断,我们看下ALLOWED_METHODS是什么

image-20211022111434536

我们发现他就是个列表,列表里面有什么呢,PUT, DELETE , PATCH

那我们是不是可以确定 _method的值了,我去们前端试下

我们用一个隐藏的input来携带 _method

<form action="http://localhost:8080/user" method="post">
    <input type="hidden" name="_method" value="delete">
    <input type="submit" value="提交delete">
</form>
<form action="http://localhost:8080/user" method="post">
    <input type="hidden" name="_method" value="delete">
    <input type="submit" value="提交put">
</form>

我们再试一遍发现成功了。

那下面的这句话是什么意思呢:

requestToUse = new HttpMethodRequestWrapper(request, method);

我们发现他只是重写了getMethod,领method为我们的请求方法,其实是为了适应delete,put...啥的

image-20211022113309863

当我们不以表单的形式使用rest时,我们什么都不用配,因为请求已经是基于http层面的修改请求方式了,下图为apiPost工具发送delete请求

image-20211022113628364

5.2.2 请求映射原理

我们的所有请求都会经过DispatcherServlet,我们分析一下他的源码,我们学过servlet 的都知道,所有的请求都会经过doservice的方法,我们研究一下他的这个方法

大部分有get、set的都是设置配置属性的,可以不用很关注,往下看我们能够发现他在doService里面调用了image-20211022183134323

doDispatch方法,我们研究一下这个方法

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HttpServletRequest processedRequest = request;
        HandlerExecutionChain mappedHandler = null;
        boolean multipartRequestParsed = false;

        WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

        try {
            ModelAndView mv = null;
            Exception dispatchException = null;

            try {
                processedRequest = checkMultipart(request);
                multipartRequestParsed = (processedRequest != request);

                // 确定当前请求的处理程序适配器
                mappedHandler = getHandler(processedRequest);
                if (mappedHandler == null) {
                    noHandlerFound(processedRequest, response);
                    return;
                }

                // Determine handler adapter for the current request.
                HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

processedRequest其实就是个request,保存请求信息

image-20211022190455171

然后就是getHandler()方法

protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
   if (this.handlerMappings != null) {
      for (HandlerMapping mapping : this.handlerMappings) {
         HandlerExecutionChain handler = mapping.getHandler(request);
         if (handler != null) {
            return handler;
         }
      }
   }
   return null;
}

我们发现他其实是从handlerMappings里面查找到这个request,那handlerMappings里面有什么呢

image-20211022190839463

RequestMappingHandlerMapping:保存了所有@RequestMapping 和handler的映射规则。

image-20211022203602254

  • SpringBoot自动配置欢迎页的 WelcomePageHandlerMapping 。访问 /能访问到index.html;
  • SpringBoot自动配置了默认 的 RequestMappingHandlerMapping
  • 请求进来,挨个尝试所有的HandlerMapping看是否有请求信息。
    • 如果有就找到这个请求对应的handler
    • 如果没有就是下一个 HandlerMapping
  • 我们需要一些自定义的映射处理,我们也可以自己给容器中放HandlerMapping。自定义 HandlerMapping

5.2.3 注解

@PathVariable、@RequestHeader、@ModelAttribute、@RequestParam、@MatrixVariable、@CookieValue、@RequestBody

@RestController
public class ParameterTestController {


    //  car/2/owner/zhangsan
    @GetMapping("/car/{id}/owner/{username}")
    public Map<String,Object> getCar(@PathVariable("id") Integer id,
                                     @PathVariable("username") String name,
                                     @PathVariable Map<String,String> pv,
                                     @RequestHeader("User-Agent") String userAgent,
                                     @RequestHeader Map<String,String> header,
                                     @RequestParam("age") Integer age,
                                     @RequestParam("inters") List<String> inters,
                                     @RequestParam Map<String,String> params,
                                     @CookieValue("_ga") String _ga,
                                     @CookieValue("_ga") Cookie cookie){


        Map<String,Object> map = new HashMap<>();

//        map.put("id",id);
//        map.put("name",name);
//        map.put("pv",pv);
//        map.put("userAgent",userAgent);
//        map.put("headers",header);
        map.put("age",age);
        map.put("inters",inters);
        map.put("params",params);
        map.put("_ga",_ga);
        System.out.println(cookie.getName()+"===>"+cookie.getValue());
        return map;
    }


    @PostMapping("/save")
    public Map postMethod(@RequestBody String content){
        Map<String,Object> map = new HashMap<>();
        map.put("content",content);
        return map;
    }


    //1、语法: 请求路径:/cars/sell;low=34;brand=byd,audi,yd
    //2、SpringBoot默认是禁用了矩阵变量的功能
    //      手动开启:原理。对于路径的处理。UrlPathHelper进行解析。
    //              removeSemicolonContent(移除分号内容)支持矩阵变量的
    //3、矩阵变量必须有url路径变量才能被解析
    @GetMapping("/cars/{path}")
    public Map carsSell(@MatrixVariable("low") Integer low,
                        @MatrixVariable("brand") List<String> brand,
                        @PathVariable("path") String path){
        Map<String,Object> map = new HashMap<>();

        map.put("low",low);
        map.put("brand",brand);
        map.put("path",path);
        return map;
    }

    // /boss/1;age=20/2;age=10

    @GetMapping("/boss/{bossId}/{empId}")
    public Map boss(@MatrixVariable(value = "age",pathVar = "bossId") Integer bossAge,
                    @MatrixVariable(value = "age",pathVar = "empId") Integer empAge){
        Map<String,Object> map = new HashMap<>();

        map.put("bossAge",bossAge);
        map.put("empAge",empAge);
        return map;

    }

}

5.2.4、Servlet API:

WebRequest、ServletRequest、MultipartRequest、 HttpSession、javax.servlet.http.PushBuilder、Principal、InputStream、Reader、HttpMethod、Locale、TimeZone、ZoneId

ServletRequestMethodArgumentResolver 以上的部分参数

@Override
public boolean supportsParameter(MethodParameter parameter) {
    Class<?> paramType = parameter.getParameterType();
    return (WebRequest.class.isAssignableFrom(paramType) ||
            ServletRequest.class.isAssignableFrom(paramType) ||
            MultipartRequest.class.isAssignableFrom(paramType) ||
            HttpSession.class.isAssignableFrom(paramType) ||
            (pushBuilder != null && pushBuilder.isAssignableFrom(paramType)) ||
            Principal.class.isAssignableFrom(paramType) ||
            InputStream.class.isAssignableFrom(paramType) ||
            Reader.class.isAssignableFrom(paramType) ||
            HttpMethod.class == paramType ||
            Locale.class == paramType ||
            TimeZone.class == paramType ||
            ZoneId.class == paramType);
}

5.2.5、复杂参数:

MapModel(map、model里面的数据会被放在request的请求域 request.setAttribute)、Errors/BindingResult、RedirectAttributes( 重定向携带数据)ServletResponse(response)、SessionStatus、UriComponentsBuilder、ServletUriComponentsBuilder

Map<String,Object> map,  Model model, HttpServletRequest request 都是可以给request域中放数据,
request.getAttribute();

Map、Model类型的参数,会返回 mavContainer.getModel();---> BindingAwareModelMap 是Model 也是Map

mavContainer.getModel(); 获取到值的

image.png

image.png

image.png

雷丰阳老师中间的这段视频我看不下去了,等到以后熟练使用以后在过来了解原理吧,有点吃不消了。

5.7、文件上传

表单

image-20211024202736275

单文件和多文件

    @PostMapping("/upload")
    public String upload(@RequestParam("email") String email,
                         @RequestParam("username") String username,
                         @RequestPart("headerImg") MultipartFile headerImg,
                         @RequestPart("photos") MultipartFile[] photos) throws IOException {

        log.info("上传的信息:email={},username={},headerImg={},photos={}",
                email,username,headerImg.getSize(),photos.length);

        if(!headerImg.isEmpty()){
            //保存到文件服务器,OSS服务器
            String originalFilename = headerImg.getOriginalFilename();
            headerImg.transferTo(new File("H:\\cache\\"+originalFilename));
        }

        if(photos.length > 0){
            for (MultipartFile photo : photos) {
                if(!photo.isEmpty()){
                    String originalFilename = photo.getOriginalFilename();
                    photo.transferTo(new File("H:\\cache\\"+originalFilename));
                }
            }
        }


        return "main";
    }

5.8 错误页面

  • 默认情况下,Spring Boot提供/error处理所有错误的映射
  • 对于机器客户端,它将生成JSON响应,其中包含错误,HTTP状态和异常消息的详细信息。对于浏览器客户端,响应一个“ whitelabel”错误视图,以HTML格式呈现相同的数据
  • imgimg
  • 要对其进行自定义,添加**View**解析为**error**`**
    **`
  • 要完全替换默认行为,可以实现 ErrorController 并注册该类型的Bean定义,或添加ErrorAttributes类型的组件以使用现有机制但替换其内容。
  • error/下的4xx,5xx页面会被自动解析;
    • img

6、数据访问

6.1、数据源的自动配置-HikariDataSource

6.1.1、依赖导入

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jdbc</artifactId>
<dependency>
<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
</dependency>

6.1.2、分析自动配置

自动配置的类
  • DataSourceAutoConfiguration : 数据源的自动配置
    • 修改数据源相关的配置:spring.datasource
    • 数据库连接池的配置,是自己容器中没有DataSource才自动配置的
    • 底层配置好的连接池是:HikariDataSource
@Configuration(proxyBeanMethods = false)
@Conditional(PooledDataSourceCondition.class)
@ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
@Import({ DataSourceConfiguration.Hikari.class, DataSourceConfiguration.Tomcat.class,
         DataSourceConfiguration.Dbcp2.class, DataSourceConfiguration.OracleUcp.class,
         DataSourceConfiguration.Generic.class, DataSourceJmxConfiguration.class })
protected static class PooledDataSourceConfiguration
  • DataSourceTransactionManagerAutoConfiguration: 事务管理器的自动配置
  • JdbcTemplateAutoConfiguration: JdbcTemplate的自动配置,可以来对数据库进行crud
    • 可以修改这个配置项@ConfigurationProperties(prefix = "spring.jdbc") 来修改JdbcTemplate
    • @Bean@Primary JdbcTemplate;容器中有这个组件
  • JndiDataSourceAutoConfiguration: jndi的自动配置
  • XADataSourceAutoConfiguration: 分布式事务相关的

6.1.3 修改配置

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/db_account
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver

6.1.4、测试

@Slf4j
@SpringBootTest
class Boot05WebAdminApplicationTests {

    @Autowired
    JdbcTemplate jdbcTemplate;


    @Test
    void contextLoads() {

//        jdbcTemplate.queryForObject("select * from account_tbl")
//        jdbcTemplate.queryForList("select * from account_tbl",)
        Long aLong = jdbcTemplate.queryForObject("select count(*) from account_tbl", Long.class);
        log.info("记录总数:{}",aLong);
    }

}

6.2 druid

官方文档:https://github.com/alibaba/druid

https://github.com/alibaba/druid/tree/master/druid-spring-boot-starter

添加场景依赖:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.17</version>
</dependency>

分析自动配置

  • 扩展配置项 spring.datasource.druid
  • DruidSpringAopConfiguration.class, 监控SpringBean的;配置项:spring.datasource.druid.aop-patterns
  • DruidStatViewServletConfiguration.class, 监控页的配置:spring.datasource.druid.stat-view-servlet;默认开启
  • DruidWebStatFilterConfiguration.class, web监控配置;spring.datasource.druid.web-stat-filter;默认开启
  • DruidFilterConfiguration.class 所有Druid自己filter的配置
private static final String FILTER_STAT_PREFIX = "spring.datasource.druid.filter.stat";
private static final String FILTER_CONFIG_PREFIX = "spring.datasource.druid.filter.config";
private static final String FILTER_ENCODING_PREFIX = "spring.datasource.druid.filter.encoding";
private static final String FILTER_SLF4J_PREFIX = "spring.datasource.druid.filter.slf4j";
private static final String FILTER_LOG4J_PREFIX = "spring.datasource.druid.filter.log4j";
private static final String FILTER_LOG4J2_PREFIX = "spring.datasource.druid.filter.log4j2";
private static final String FILTER_COMMONS_LOG_PREFIX = "spring.datasource.druid.filter.commons-log";
private static final String FILTER_WALL_PREFIX = "spring.datasource.druid.filter.wall";

配置示例

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/db_account
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver

    druid:
      aop-patterns: com.atguigu.admin.*  #监控SpringBean
      filters: stat,wall     # 底层开启功能,stat(sql监控),wall(防火墙)

      stat-view-servlet:   # 配置监控页功能
        enabled: true
        login-username: admin
        login-password: admin
        resetEnable: false

      web-stat-filter:  # 监控web
        enabled: true
        urlPattern: /*
        exclusions: '*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*'


      filter:
        stat:    # 对上面filters里面的stat的详细配置
          slow-sql-millis: 1000
          logSlowSql: true
          enabled: true
        wall:
          enabled: true
          config:
            drop-table-allow: false

参数对照表:

https://github.com/alibaba/druid/wiki/DruidDataSource%E9%85%8D%E7%BD%AE%E5%B1%9E%E6%80%A7%E5%88%97%E8%A1%A8

6.3、整合MyBatis操作

https://github.com/mybatis

SpringBoot官方的Starter:spring-boot-starter-*

第三方的: *-spring-boot-starter

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.4</version>
</dependency>

image.png

1、配置模式

  • 全局配置文件
  • SqlSessionFactory: 自动配置好了
  • SqlSession:自动配置了 SqlSessionTemplate 组合了SqlSession
  • @Import(AutoConfiguredMapperScannerRegistrar.class);
  • Mapper: 只要我们写的操作MyBatis的接口标准了 @Mapper 就会被自动扫描进来
@EnableConfigurationProperties(MybatisProperties.class) : MyBatis配置项绑定类。
@AutoConfigureAfter({ DataSourceAutoConfiguration.class, MybatisLanguageDriverAutoConfiguration.class })
public class MybatisAutoConfiguration{}

@ConfigurationProperties(prefix = "mybatis")
public class MybatisProperties

可以修改配置文件中 mybatis 开始的所有;

# 配置mybatis规则
mybatis:
  config-location: classpath:mybatis/mybatis-config.xml  #全局配置文件位置
  mapper-locations: classpath:mybatis/mapper/*.xml  #sql映射文件位置
  
Mapper接口--->绑定Xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.admin.mapper.AccountMapper">
<!--    public Account getAcct(Long id); -->
    <select id="getAcct" resultType="com.atguigu.admin.bean.Account">
        select * from  account_tbl where  id=#{id}
    </select>
</mapper>

配置 private Configuration configuration; mybatis.configuration下面的所有,就是相当于改mybatis全局配置文件中的值

# 配置mybatis规则
mybatis:
#  config-location: classpath:mybatis/mybatis-config.xml
  mapper-locations: classpath:mybatis/mapper/*.xml
  configuration:
    map-underscore-to-camel-case: true
    
 可以不写全局;配置文件,所有全局配置文件的配置都放在configuration配置项中即可
  • 导入mybatis官方starter
  • 编写mapper接口。标准@Mapper注解
  • 编写sql映射文件并绑定mapper接口
  • 在application.yaml中指定Mapper配置文件的位置,以及指定全局配置文件的信息 (建议;配置在mybatis.configuration

2、注解模式

@Mapper
public interface CityMapper {

    @Select("select * from city where id=#{id}")
    public City getById(Long id);

    public void insert(City city);

}

3、混合模式

@Mapper
public interface CityMapper {

    @Select("select * from city where id=#{id}")
    public City getById(Long id);

    public void insert(City city);

}

最佳实战:

  • 引入mybatis-starter
  • 配置application.yaml中,指定mapper-location位置即可
  • 编写Mapper接口并标注@Mapper注解
  • 简单方法直接注解方式
  • 复杂方法编写mapper.xml进行绑定映射
  • @MapperScan("com.atguigu.admin.mapper") 简化,其他的接口就可以不用标注@Mapper注解
最后修改:2021 年 10 月 28 日 10 : 19 AM