SpringBoot

第1章 XML和JavaConfig

概述

  1. spring和springMVC都有一个容器的概念,都需要写大量的配置文件。

    配置文件越多,在使用上越麻烦,越容易出错。

  2. springboot可以让我们少写配置。通过springboot框架,我们可以很少写配置文件,我们可以直接在项目中使用。

    可以理解为,用springboot能够实现spring、spirngMVC的功能,而不用再写之前那些配置文件就可以使用了。

    可以理解为是更加快速的spring和springMVC

  3. 为什么要使用springboot

    因为spring、springMVC需要使用大量的配置文件(xml文件,即使是采用注解,也需要配置文件里写组件扫描器之类的),还需要配置各种对象,把使用的对象放入到spring和springmvc容器中才能使用对象。

    那么就需要了解其他框架的配置规则。

    springboot相当于是不需要配置文件的spring + springMVC。并且常用的框架和第三方库都已经配置好了,开箱即用。

    使用springboot开发效率高。

JavaConfig

  1. spring本来是使用XML配置文件作为容器配置文件,在3.0以后加入了JavaConfig,使用Java类做配置文件使用。

  2. JavaConfig是spring提供的Java类配置容器,是配置spring容器的纯Java方法。

    也就是现在配置spring容器,不需要写xml配置文件了,用Java类来当作配置文件。

  3. 在这个Java配置类可以创建Java对象,把对象放入spring容器中!

  4. Java配置类需要两个注解的支持。

    • @Configuration---放在类上面

      作用:放在一个类的上面,表示这个类作为配置文件使用,这个类就相当于XML文件了。

    • @Bean----放在方法上面

      作用:声明对象,把对象注入到容器中。

    使用方式:

    /**
     * @Configuration: 表示当前类是作为配置文件使用的, 就是用来配置spring容器的,也就是配置spring容器中的对象的。
     * 位置:写在类的上面。
     * SpringConfig这个类就相当于bean.xml
     */
    @Configuration
    public class SpringConfigure {
    
        /**
         * 创建方法,方法的返回值是对象,在方法的上面加入@Bean
         * 这个返回的对象就会注入到spring容器中
         *
         * @Bean:把返回的对象注入到spring容器中
         * 这个注解的作用就相当于原spring容器xml配置文件中的 <bean></bean>
         *
         * 说明:@Bean,如果不指定对象的名称,默认方法名是对象在容器中的名字即id
         */
        @Bean
        public Student createStudent() {
            Student s1 = new Student();
            s1.setName("张三");
            s1.setAge(26);
            s1.setSex("男");
            return s1;
        }
    
        /**
         * @Bean,指定对象在容器中的名称即id
         */
        @Bean(name = "lisiStudent")
        public Student makeStudent() {
            Student s2 = new Student();
            s2.setName("李四");
            s2.setAge(26);
            s2.setSex("男");
            return s2;
        }
    }
    
  5. 在项目中,这种配置类可以有若干个,这些类被当作spring容器的配置文件来用!!

    就是用Java类(配置类)的形式来完成原XML配置文件的作用。

  6. 优点:

    • 可以使用面向对象的方式,一个配置类可以继承配置类,可以重写方法。
    • 避免繁琐的XML配置

两个注解介绍

@ImportResource

  1. @ImportResource是导入其他XML配置文件,等同于XML文件的<import resources="配置文件"/>

    如果现在有些bean的配置是放在XML配置文件之中,但是现在想用JavaConfig的方式来配置容器,那么可以用这个注解来利用已存在的XML配置文件。

  2. @Configuration
    @ImportResource(value = "classpath:applicationContext.xml")
    public class SpringConfigure {
    

    属性可以用value 也可以用locations,它们互为别名,是一个意思,指定需要导入的其他XML配置文件。

    classpath是类路径即target/classes,如果不知道类路径,那么可以编译之后看一下。

  3. 如果需要利用已存在的多个XML配置文件,那么就在value里指定多个,value指定的值是数组。

    image-20220109172015393

@PropertyResource

  1. 读取属性配置文件,也就是xxx.properties配置文件

  2. 最常见是把数据库的配置文件放在properties配置文件中,那么可以通过这个注解读取到。

    image-20220109172632702

  3. 使用属性配置文件可以实现外部化配置,在程序代码之外提供数据

  4. 步骤:

    • 在resources目录下,创建properties文件,使用k=v的格式提供数据
    • 在PropertyResource指定properties文件的位置
    • 使用@Value("${key}")
    @PropertySource(value = "classpath:config.properties")
    @ComponentScan(basePackages = "org.example.vo")
    public class SpringConfigure {
    

    @ComponentScan作用是扫描包,将用注解声明的对象,放到容器中,和之前用XML配置文件的方式是一样的,即使是通过注解创建对象,要配置组件扫描器,这个注解就相当于组件扫描器。

    而@PropertyResource就是指定properties文件的位置

  5. 为什么@PropertyResource和@ImportResource这些注解要写在SpringConfigure这个类上面,因为这个类上面有@Configure注解,说明这是一个配置类,是来配置spring容器的。

    把这个类当作配置文件就好,之前的组件扫描器等都是写在此XML配置文件中的。

    那么这些配置的注解都写在@Configure这个配置类上面

第2章 springboot入门

概述

  1. springboot是spring大家族中的一个成员,可以简化spring、springMVC的使用,他的核心仍然是IOC容器。

  2. 特点:

    • 创建一个独立的spring应用

    • 内嵌tomcat服务器,就是说不用单独安装tomcat,就能执行web应用。

    • 提供starter起步依赖,来简化应用的配置。----自动导入、管理jar包

      以前依赖的jar包的版本必须控制好,都是自己去控制、添加依赖,现在springboot给我们提供了starter启动器,假如我们想要开发web应用,我们只需要添加一个web的启动器依赖,不需要管理其他web开发需要的jar包,springboot自动管理jar包,并且保证jar包的版本

      starter可以理解为是我们某一个开发场景的全部依赖,springboot都给我们导入,相当于导入我们某一个开发场景的开发环境。

    • 尽可能自动配置spring和第三方库。----自动配置,这一点是强调配置文件。

      比如说我们要使用mybatis框架,需要在spring项目中,配置dataSource,配置mybatis的对象SqlSessionFactory,还有dao的代理对象。

      在springboot项目中,自动配置好了。

      不用像以前整合mybatis、spring、springmvc要写一大堆配置

      这些配置现在springboot自动配置

      专注我们的业务逻辑

    • 提供生产级别的监控、健康检查及外部化配置

    • 不用生成代码,不用使用XML去做配置。

使用springboot

第一种方式: 使用springboot提供的初始化器

  1. 这是使用spring官方提供的初始化器。通过https://start.spring.io

    通过这种方式构建springboot项目时,以下是初始化能选择的依赖,我们开发要用到的依赖和场景可以在这里选择。

    image-20220109191345685

  2. 构建好了之后,项目结构如下:

    image-20220109191851866

    mvnw和mvnw.cmd相当于是maven增强的工具,springboot项目也是通过maven来管理的,比如说我们在控制台执行mvn clean 或mvn install等命令的时候,如果没有安装maven,那么会自动帮我们安装,这是这两个文件的作用。

  3. image-20220109192058645

    main目录下,是功能实现类。

    resources下是放资源文件的

    • static下是放静态资源的,比如js文件、css文件、html文件、图片等。
    • templates是放模板文件的(用于视图层的)
    • application.properties是springboot的配置文件
  4. pom文件

    <?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <!--springboot项目的父项目-->
        <!--父项目是管理依赖和依赖版本的。-->
        <!--和springboot项目有关的依赖和版本都是在父项目中来定义和声明的。-->
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.4.2</version>
            <relativePath/>
        </parent>
    
        <!--当前项目的gav即坐标-->
        <groupId>com.bjpowernode</groupId>
        <artifactId>springboot-02</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    
        <properties>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
            <!--
                我们自己选择的开发场景的依赖
                可以看到这里没有写版本号,因为用的是父项目中规定好的版本号。
            -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <!--做测试的-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <!--springboot项目用到的maven的插件,用来打包、构建等工作-->
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>
    
    
  5. image-20220109193243155

    发现一个starter,就引用了好多相关的依赖,springboot都帮我们导入好了。

    我们在pom文件中,并没有显示地添加springmvc的依赖,但是这里已经导入了。就是通过starter,将某一个场景相关的依赖都导入进来。

第二种方式:使用maven构建springboot项目

  1. 需要我们自己去创建springboot项目的目录、pom文件里添加依赖。

  2. 这是一个maven项目的pom文件,添加spring-boot-starter-parent

    image-20220109194501005

    那么现在就是基于springboot框架的了。

    接着添加依赖

    image-20220109194529828

    这就可以基于springboot做web开发了。

  3. resources资源目录下所需要的配置文件和目录也需要对应建立出来。

  4. springboot把我们做开发所需要的配置都配置好了,比如web开发,我们不需要自己去配置springmvc,不需要些springmvc配置文件,包括中央调度器或者说前端控制器DispatcherServlet也已经配置好了。

@SpringBootApplication注解

概述

  1. 我们通过主方法启动springboot项目。

    这个类叫主启动类。

    在主启动类上面一定有@SpringBootApplication这个注解

  2. image-20220109195902935

  3. @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    这几个注解叫元注解信息,比如@Target({ElementType.TYPE})是说@SpringBootApplication用在类之上的。
    @Retention(RetentionPolicy.RUNTIME)是说@SpringBootApplication是在运行期起作用
    
  4. 可以看到@SpringBootApplication这个注解是一个复合注解,是由多个注解的功能所组成的,主要是以下三个注解

    @SpringBootConfiguration
    @EnableAutoConfiguration
    @ComponentScan
    

@SpringBootConfiguration

  1. @SpringBootConfiguration

    image-20220109200259743

    说明@SpringBootConfiguration这个注解的作用应该和@Configuration是保持一致的,也就是说被@SpringBootConfiguration注解标注的类,能够当作配置类即JavaConfig,就可以定义Bean,把对象注入到容器中。如下:

    image-20220109200749417

@EnableAutoConfiguration

  1. @EnableAutoConfiguration

    启动自动配置。

    把Java对象配置好,注入到spring容器中。例如可以把mybatis的对象创建好,放入到容器中。

    自动配置强调配置文件,starter是强调起步的依赖、jar包。

    比如我们以前整合mybatis,那么需要在spring配置文件中,写dataSource配置、SessionFactory配置以及dao接口的对象的配置。现在这些配置不需要写,由springboot帮我们做。这就是自动配置。

    我们通过这个注解,可以拿到我们用mybatis所需要的对象,但是我们并没有配置。

    以前没有用springboot的时候,做ssm整合,在spring的xml配置文件里写很多配置。如下,就称为配置:

    
        <!--spring配置文件:声明dao、service、工具类等对象,将对象交给容器创建-->
        <context:property-placeholder location="classpath:conf/jdbc.properties" />
        <!-- 声明数据源,连接数据库-->
        <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
            <property name="url" value="${jdbc.url}"/>
            <property name="username" value="${jdbc.username}"/>
            <property name="password" value="${jdbc.password}"/>
        </bean>
    
        <!--SqlSessionFactoryBean创建SqlSessionFactory-->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource"/>
            <property name="configLocation" value="classpath:conf/mybatis.xml"/>
        </bean>
    
        <!--声明mybatis的扫描器,创建dao接口的实现类对象(通过动态代理。实现类不需要写,但是service的实现类是要写的)-->
        <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
            <property name="SqlSessionFactoryBeanName" value="sqlSessionFactory"/>
            <property name="basePackage" value="org.example.dao"/>
        </bean>
    

    现在这些配置不需要我们写了。

@ComponentScan

  1. @ComponentScan

    组件扫描器。

    通过这个注解能够找到添加了注解(@Component、@Controller等)的其他类,找到注解,根据注解的功能创建对象,给属性赋值等等。

    image-20220109202039561

    我们写这个代码,在这个类上面添加了@Controller,但是我们并没有添加组件扫描器,在容器中仍然有这个Controller对象,原因就是@SpringBootApplication这个注解里的@ComponentScan是个组件扫描器。

    如果我们不用springboot开发,用ssm的时候,一定要配置组件扫描器,来找到@Controller注解修饰的Controller对象,并注入到容器中。如下:

        <!-- springmvc配置文件,声明controller和其他web相关的对象-->
        <context:component-scan base-package="org.example.controller"/>
    

    @Controller、@Service、@Repository、@Component注解是创建对象,那么组件扫描器就是找到对象并放在容器中。

  2. image-20220109202809633

    主启动类是在主包下面,Controller类是在主包的子包下面。

    组件扫描器的规则:

    默认扫描的包是@ComponentScan所在的类所在的包和子包。

springboot配置文件

概述

  1. 配置文件名称:application
  2. 扩展名有:
    • .properties(k=v)
    • .yml(k: v)

properties格式

  1. 里面有各种配置项。

    ## 设置端口号。
    server.port=8082
    #设置访问应用的上下文路径
    server.servlet.context-path=/myboot
    

yml格式

  1. 可读性更强。

  2. 冒号、空格必须有。

    server:
      port: 8083
      servlet:
        context-path: /myboot2
    
  3. 当两种格式的配置文件同时存在,从springboot开始,使用yml配置文件。

多环境配置

  1. 在实际开发的过程中,我们的项目会经历很多阶段,比如开发、测试、上线。

    每个阶段的配置都不同,例如:端口、上下文根、数据库url、用户名、密码等等。那么这个时候为了方便在不同的环境之间切换,springboot提供了多环境配置。

  2. 使用方式:

    为每个环境创建一个配置文件,命名必须为application-环境标识.properties/yml

    比如创建开发环境的配置文件:application-dev.properties/yml

    比如创建测试环境的配置文件:application-test.properties/yml

  3. 在application.properties/yml文件中指定激活哪个配置文件。

    #激活使用哪个配置文件
    spring.profiles.active=dev
    

springboot自定义配置

  1. springboot核心配置文件中,除了使用内置的配置项之外,我们还可以自定义配置,然后采用如下注解去读取配置的属性值。

    • @Value("${key}"),key来自application.properties/yml

      之前说的JavaConfig,用Java类来代替XML配置文件,是说的xml容器配置文件,Java类的作用是创建对象,并将对象注入到容器,这个类用@Configuration注解修饰,要结合@Bean注解,@Bean注解就相当于原来XML文件里<bean>

      而现在这里说的配置文件是指springboot配置文件.properties或.yml,在开发中,此配置文件里的值也可以用类来接收(此类的名称可能会取为XxxConfig),并且给属性赋值,通过@Value("${key}")的方式。而此类不是之前说的用@Configuration修饰的类,不要弄混了。下面就会介绍@ConfigurationProperties注解,对应于.properties/yml文件,和@Configuration不一样,就是说的这个意思。

      application.properties/yml配置的值可以通过@Value注解给属性赋值。

    • @ConfigurationProperties

      将整个文件映射成一个对象,用于自定义配置项比较多的情况。

      image-20220109214455395

      image-20220109214513064

springboot中使用jsp

  1. 用springboot框架,默认不支持jsp,也不推荐用jsp。

    jsp会慢慢被淘汰掉,我们会用模板引擎技术来替代jsp

  2. Thymeleaf是一个流行的模板引擎,该模板引擎采用Java语言开发。

    Thymeleaf对网络环境不存在严格的要求,既能用于web环境下,也能用于非web环境下。

    在非web环境下,能直接显示模板上的静态数据,在web环境下,它能像jsp一样从后台接收数据并替换掉模板上的静态数据。它是基于HTML的,以HTML标签为载体,thymeleaf要寄托在html标签下实现。

    springboot继承了thymeleaf模板技术来替代jsp技术,作为前端页面的数据展示,在过去的Javaweb开发中,我们往往会选择使用jsp来完成页面的动态渲染,但是jsp需要翻译编译运行,效率低。

springboot中使用ApplicationContext

  1. 在main方法中通过SpringApplication.run()方法获取返回的spring容器对象,再获取业务bean进行调用。

  2. 此run方法的返回值就是容器.

    @SpringBootApplication
    public class Springboot03Application {
    
        public static void main(String[] args) {
            SpringApplication.run(Springboot03Application.class, args);
        }
    
    }
    

    获取到容器对象之后,我们就能通过getBean方法获取容器中的对象,就和没有使用springboot的时候是一样的。

     public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
            return run(new Class[]{primarySource}, args);
        }
    

    ConfigurableApplicationContext是一个接口,是ApplicationContext的子接口,所以这个返回值就是一个接口。

    image-20220110134309826

    这种就是一般自己做测试的时候可以使用这种方法。

springboot中使用CommandLineRunner接口

  1. 开发中可能会有这样的场景,需要在容器启动后,执行一些内容,比如读取配置文件,连接数据库等等。

    springboot给我们提供了两个接口来帮助我们实现这种需求。这两个接口分别为CommandLineRunner和ApplicationRunner。

    它们的执行时机为容器启动完成的时候

    这两个接口中有一个run方法,我们只需要实现这个run方法即可。

  2. 这两个接口的不同之处在于:

    • ApplicationRunner接口中run方法的参数为ApplicationArguments

      @FunctionalInterface
      public interface ApplicationRunner {
          void run(ApplicationArguments args) throws Exception;
      }
      
    • CommandLineRunner接口中run方法的参数为String数组

      @FunctionalInterface
      public interface CommandLineRunner {
          void run(String... args) throws Exception;
      }
      

    这两个接口用哪个都可以,他们的作用是一样的。

    执行时间是在容器对象创建好之后,自动执行run()方法,所以我们只需要重写这个run()方法。

  3. 我们可以通过此方法完成容器创建好之后自动执行的一些操作。

    @SpringBootApplication
    public class Springboot03Application implements CommandLineRunner {
    
        public static void main(String[] args) {
            System.out.println("准备创建容器对象");
            // 在这个run方法里面是调用了下面定义的这个run方法,这是两个不同的run方法。
            SpringApplication.run(Springboot03Application.class, args);
            System.out.println("容器对象创建之后");
        }
    
        // 这个run方法是在容器对象创建之后执行的,而容器对象创建好,说明容器中的对象也创建好并放在容器中了,说明在这个run方法里面可以获取到容器中的对象。
        @Override
        public void run(String... args) throws Exception {
            // 可以做一些自定义的操作,比如读取文件、数据库等。
            System.out.println("容器对象创建好后执行的方法");
        }
    }
    

第3章 springboot和web组件

springboot中使用拦截器

  1. 拦截器是springMVC中的一种对象,这种拦截器能拦截对Controller的请求。

  2. 拦截器框架中有系统的拦截器,还可以自定义拦截器,实现对请求预处理

  3. 在springMVC框架中实现自定义拦截器:

    • 创建springMVC框架中的HandlerInterceptor接口的是实现类。

    • 需要把第一步创建的类注入到容器中。

      image-20220111124346613

  4. 在springboot中实现拦截器的步骤:

    • 先写自定义拦截器类,并实现HandlerInterceptor接口

      // 自定义拦截器
      public class LoginInterceptor implements HandlerInterceptor {
          /**
           *
           * @param request
           * @param response
           * @param handler 被拦截的控制器对象
           * @return boolean
           *          true: 能被Controller处理
           *          false:请求被截断
           * @throws Exception
           */
          @Override
          public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
              System.out.println("执行了LoginInterceptor拦截器");
              return false;
          }
      }
      
    • 创建Config类,来代替原来在springmvc中写的springmvc xml配置文件,来注册拦截器

      // 原先要实现拦截器,要写springmvc XML配置文件,现在是把配置文件移到了这个WebMvcConfigurer接口的方法之中。
      // 加了这个注解的类就和没有使用springboot的时候的XML配置文件是对应的。
      @Configuration
      public class MyAppConfig implements WebMvcConfigurer {
          //添加拦截器对象,并注入到容器中
          @Override
          public void addInterceptors(InterceptorRegistry registry) {
              // 创建拦截器对象
              HandlerInterceptor handlerInterceptor = new LoginInterceptor();
              // 拦截器对象注入到容器中
              InterceptorRegistration interceptorRegistration = registry.addInterceptor(handlerInterceptor);
              // 指定拦截器拦截的地址即url
              String[] path = {"/user/**"};
              // 指定拦截器不拦截的地址
              String[] excludePath = {"/user/login"};
              interceptorRegistration.addPathPatterns(path).excludePathPatterns(excludePath);
          }
      }
      

springboot中使用servlet

  1. 使用步骤:
    • 创建Servlet类,创建类继承HttpServlet类

      public class MyServlet extends HttpServlet {
          @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              doPost(req, resp);
          }
      
          @Override
          protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              // 使用HttpServletResponse输出数据,应答结果
              resp.setContentType("text/html;charset=urf-8");
              PrintWriter pw = resp.getWriter();
              pw.println("执行的是servlet1111111Response");
              pw.flush();
              pw.close();
      
          }
      }
      
    • 注册第一步创建的Servlet类,即创建出对象并注入到容器中,让框架能够找到。

          @Bean
          public ServletRegistrationBean servletRegistrationBean() {
              // 以下是有参构造器,第一个参数是Servlet对象,第二个参数是url
              //public ServletRegistrationBean(T servlet, String... urlMappings)
              ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new MyServlet(), "/myservlet");
              return servletRegistrationBean;
      
          }
      

      和拦截器一样,这是往容器中注入Servlet对象,使用的@Bean注解,相当于以前的bean标签,那么这个方法要写在@Configuration修饰的类里,此类为配置类,和XML配置文件的作用是一样的。

      或者不采用构造函数的方式为ServletRegistrationBean设置参数,采用set方法也是一样的。

              servletRegistrationBean.setServlet(new MyServlet());
              servletRegistrationBean.addUrlMappings("/myservlet");
      

springboot中使用过滤器

  1. 过滤器的作用:

    用户的请求先经过过滤器,在过滤器中对请求的参数做处理。

    过滤器是先于拦截器执行的。

    我们用过滤器最常用的是处理字符集。

  2. 在springboot中使用自定义过滤器的步骤

    • 创建自定义过滤器类。

      public class MyFilter implements Filter {
          @Override
          public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
              System.out.println("执行过滤器方法");
              filterChain.doFilter(servletRequest, servletResponse);
          }
      }
      
    • 注册Filter过滤器对象。

          @Bean
          public FilterRegistrationBean filterRegistrationBean() {
              FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
              filterRegistrationBean.setFilter(new MyFilter());
              filterRegistrationBean.addUrlPatterns("/myservlet");
              return filterRegistrationBean;
          }
      
  3. 字符集过滤器

    CharacterEncodingFilter:解决post请求中乱码的问题。

    在SpringMVC框架,在web.xml中注册过滤器,配置属性。

    CharacterEncodingFilter不是我们自定义的,是springmvc框架的。

  4. 自己配置字符集过滤器

    image-20220111153801895

    并修改application.properties配置文件,目的是让自定义的过滤器起作用。

    image-20220111151328661

  5. 不自己去配置过滤器,就用springboot自带的过滤器CharacterEncodingFIlter

    在application.properties配置文件中进行配置:

    image-20220111154507023

第4章 ORM操作MySQL

概述

  1. 使用mybatis框架操作数据,在springboot框架继承mybatis

使用

步骤

  1. mybatis起步依赖starter:完成mybatis对象自动配置,对象放在容器中。

    (之前mybatis和spring集成的时候,就是将mybatis相关的对象都交给spring容器管理,让spring容器来创建并管理mybatis的对象)

  2. pom.xml文件中指定/src/main/java目录中的xml文件包含到类路径中

      <build>
        <resources>
          <resource>
            <directory>src/main/java</directory>
            <includes><!-- 包括目录下的.properties,.xml文件都会扫描到 -->
              <include>**/*.properties</include>
              <include>**/*.xml</include>
            </includes>
          </resource>
        </resources>
      </build>
    
  3. 创建实体类Student

  4. 创建Dao接口StudentDao,创建查询学生的方法(不用创建接口的实现类)

    /**
     * @Mapper:告诉mybatis这是dao接口,创建此接口(的实现类)的代理对象
     */
    @Mapper
    public interface StudentDao {
        Student selectStudentById(@Param("stuId") Integer id);
    }
    
  5. 创建dao接口对应的mapper XML文件,写sql语句

  6. 创建Service层对象,创建StudentService接口和他的实现类,调用dao对象的方法,完成数据库的操作。但是dao接口的实现类我们并没有写,dao接口的实现类的对象是由mybatis创建,底层是动态代理的方式,我们并不需要写实现类

  7. 创建Controller对象,调用service

  8. 写application.properties配置文件配置数据库的连接信息。

第一种方式:@Mapper注解

  1. @Mapper注解,放在dao接口的上面,每个接口都使用这个注解。

    /**
     * @Mapper:告诉mybatis这是dao接口,创建此接口(的实现类)的代理对象
     */
    @Mapper
    public interface StudentDao {
        Student selectStudentById(@Param("stuId") Integer id);
    }
    

    通过@Mapper找到对应的接口,并创建dao接口的代理对象。

第二种方式:@MapperScan注解

  1. 在dao接口上面加入注解,需要在每个dao接口的上面都加入注解,当接口多的时候不方便。

    这种方式只需要在主启动类上加上@MapperScan注解,并指定dao接口所在的包名。

    通过属性basePackages指定多个包。

    image-20220111170450011

    image-20220111170831002

dao接口和mapper文件分开存储

  1. 把mapper映射文件放在resources目录中

    在resources目录中创建子目录,例如mapper

    把mapper文件放入mapper目录中。

  2. 我们需要告诉框架,到哪里去找dao接口所对应的mapper文件

    在application.properties配置文件中配置:

    #指定mapper文件的位置
    mybatis.mapper-locations=classpath:mapper/*.xml
    #指定mybati的日志
    mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
    

事务支持

  1. springboot使用事务非常简单,底层依然是采用的是spring本身提供的事务管理。

    • 在入口类使用注解@EnableTransactionManagement开启事务支持
    • 在访问数据库的Service方法上加注解@Transactional即可。
  2. spring框架中的事务

    • 管理事务的对象:事务管理器(接口),这个接口有很多的实现类,这些不同的实现类负责不同的数据库访问技术的事务管理

      例如:使用JDBC或mybatis访问数据库,使用的事务管理器:DataSourceTransactionManager,这需要在spring配置文件中进行配置。

    • 声明式事务:

      在xml配置文件或者使用注解说明事务控制的内容。

      控制事务:隔离级别、传播行为、超时时间。

    • 事务的处理方式:

      • spring框架中的注解@Transactional
      • aspecj框架,可以在xml配置文件中声明事务控制的内容。
  3. springboot中使用事务,第2点提到的两种事务处理方式都可以用。

    • 在业务方法上,加@Transactional,加入注解后,方法就有事务功能了。
    • 明确地在主启动类上面,加入@EnableTransactionManagement

第5章 接口架构风格-RESTful

概述

  1. 这里接口的定义:

    来自百度:

    image-20220111175339693

  2. 架构风格:

    API组织方式,如下就是一个传统的风格。

    image-20220111233229358

    在地址上提供了访问的资源名称,addStudent,在其后使用了get方法请求,传递参数。

  3. RESTful架构风格

    REST(表现层状态转移)是一种互联网软件架构设计的风格,但它并不是标准,它只是提出了一组客户端和服务器交互时的架构理念和设计原则。

    image-20220111233512942

    基于这种风格的API组织方式,更简洁、更有层次。

  4. REST中的要素:

    用REST表示在互联网中,一个资源或一个操作。

    资源使用url表示的,在互联网,使用的图片、文本、视频、网页等都是资源。

  5. 使用http中的动作(请求方式),表示对资源的操作(CRUD)

    • GET:查询资源---sql select
    • POST:创建资源---sql insert
    • PUT:更新资源---sql update
    • DELETE:删除资源---sql delete

    浏览器能够直接支持的请求方式是GET和POST,所以我们基本只用前两个,POST可以代替PUT和DELETE

    REST风格,在url中,使用名词表示资源,以及访问资源的信息,用/来分割资源的信息

    image-20220111235040462

    image-20220111235708371

  6. 需要的分页、排序等参数,依然放在url的后面,例如:

    image-20220112000104419

  7. 一句话说明REST:

    在url中,使用名词表示资源,使用http动作(四种请求方式)来操作资源。

  8. springboot开发RESTful主要是几个注解实现。

  9. 在页面中或者ajax中,支持put、delete请求:

    过滤器:org.springframework.web.filter.HiddenHttpMethodFilter

    作用:把请求中的post转为put、delete

    在springboot中,用这个过滤器:

    • 在application.properties/yml文件中,开启使用HiddenHttpMethodFilter过滤器

      image-20220113145837923

    • 在请求页面中,包含_method参数,它的值是put、delete,但是发起这个请求真实使用的是post方式。

      image-20220113145907602

RESTful的注解

@PathVariable

  1. 获取URL中的数据,该注解是实现RESTful最主要的一个注解。

  2. 比如此url

    image-20220112002815522

    用普通的getParameter的方式拿不到数据,因为“1001”不是在“?”号后的这种传参方式

    我们要从这个url的路径中获取数据

  3. 使用:

    @RestController
    public class MyRestController {
    
        /**
         * @PathVariable 路径变量:获取url中的数据
         *              属性:value:路径变量名
         *              位置:放在控制器方法形参前面
         * {stuId}:定义路径变量名,自定义名称,保证和@PathVariable注解的value属性值一样
         * @param studentId
         * @return
         */
        @GetMapping("/student/{stuId}")
        public String getStudent(@PathVariable(value = "stuId") Integer studentId) {
            return "查询学生studentId" + studentId;
        }
    }
    

    注意:

    • 这种方式只能适用于请求参数是简单类型的形参而不能是对象形参。

    • 当路径变量名和形参名是一样的时候,@PathVariable注解的value属性可以省略不写。

      image-20220113135215392

@GetMapping

  1. 支持get的请求方式

    等同于@RequestMapping(method=RequestMethod.GET)

@PostMapping

  1. 接收和处理post方式的请求

    等同于@RequestMapping(method=RequestMethod.POST)

@PutMapping

  1. 支持put请求方式。

    等同于@RequestMapping(method=RequestMethod.PUT)

@DeleteMapping

  1. 支持delete请求方式。

    等同于@RequestMapping(method=RequestMethod.DELETE)

@RestController

  1. 复合注解,是@Controller和ResponseBody组合

  2. 在类的上面使用@RestController,表示当前类的所有方法都加上了@ResponseBody注解,@ResponseBody注解的意思是说用对象来表示处理请求之后的返回值。即控制器方法的返回值为对象

    如果返回值是String,但是加上了@ResponseBody注解,那么返回的字符串代表数据而不是视图。

    @ResponseBody是表示返回的对象是数据,和视图无关,可以用来处理ajax请求,控制器方法返回的是一个对象,那么将对象先进行转换,转换为某格式的字符串,再通过@ResponseBody注解进行输出。

    如何处理呢?

    • 注解驱动将返回的对象转换为对应格式的字符串
  • @ResponseBody注解将json、xml、txt格式的字符串,通过HttpServletResponse输出给浏览器

postman

  1. 自己写接口测试的话,如果用浏览器测试,那么只能测试GET请求,通过浏览器地址栏的形式是测试不了POST请求的,可以用postman。
  2. 这是一个工具,可以对编写的API进行测试。

第6章 springboot集成redis

概述

  1. Redis是一个NoSQL数据库,常用作缓存Cache使用,通过redis客户端可以使用多种语言在程序中,访问redis数据,Java语言中使用的客户端库有Jedis,lettuce,Redission等

  2. NoSQL的No的意思是说Not only,就是说不仅仅是数据库,不仅仅用来存数据,还能干别的事情。性能好,单线程,当作缓存使用,不涉及CPU和磁盘的交互,所以单线程,不需要多线程来提升CPU的利用率。用redis来减少程序对真正的数据库的访问的压力,来提升性能

  3. springboot中使用RedisTemplate(StringRedisTemplate)模板类来完成和redis数据的交互(CRUD)

  4. redis是一个中间件,是一个独立的服务器,是独立的可以单独使用的。

    zookeeper也是属于中间件,也是一个独立的服务器,是一个注册中心,是一个单独的应用程序。

步骤

  1. 添加依赖

    RedisTemplate使用的lettuce这个客户端库。

            <!--
    		redis起步依赖,就可以直接在项目中使用RedisTemplate(StringRedisTemplate)
    		data-redis使用的lettuce这个客户端库,在程序中使用RedisTemplate类的方法,实际就是调用lettuce这个客户端库中的方法
    		-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
    
  2. 配置redis服务端信息

    #指定redis信息(host ip password)
    spring.redis.host=localhost
    spring.redis.port=6379
    
  3. 写程序,用RedisTemplate进行数据的添加,添加进redis。

    @RestController
    public class RedisController {
        //注入RedisTemplate
        /**
         * RedisTemplate泛型
         * RedisTemplate<String, String>
         * RedisTemplate<Object, String>
         * RedisTemplate
         *
         * 注意:RedisTemplate对象的名称为redisTemplate
         * 按@Resource注入的时候默认是按byName
         */
        @Resource
        private RedisTemplate redisTemplate;
        /**
         *
         * @param keyName
         * @param value
         * @return
         */
        @PostMapping("/redis/addString")
        public String addToRedis(String keyName, String value) {
            //操作String类型的数据,要先获取ValueOperations对象
            // 就是说 操作不同类型的数据,要根据redisTemplate获取不同对象
            ValueOperations valueOperations = redisTemplate.opsForValue();
            valueOperations.set(keyName, value);
            return "向redis添加string类型的数据";
        }
    
        @GetMapping("/redis/getKey")
        public String getData(String keyName) {
            ValueOperations valueOperations = redisTemplate.opsForValue();
            Object v = valueOperations.get(keyName);
            return "key:" + keyName + " value:" + v;
    
        }
    }
    

序列化

  1. 序列化:

    序列化:把对象转换为可传输的字节序列(二进制)过程称为序列化

    ​ 序列化可以转换成二进制也可以转换为某种格式

    反序列化:把字节序列还原为对象的过程称为反序列化。

  2. 为什么需要序列化:

    序列化最终的目的是为了对象可以跨平台存储,和进行网络传输,而我们进行跨平台存储和网络传输的方式就是IO,而IO支持的数据格式就是字节数组

    我们必须在把对象转换成字节数组的时候制定一种规则(序列化),那么我们从IO流里面读出数据的时候再以这种规则把对象还原回来(反序列化)

  3. image-20220113164317002

  4. JSON序列化:

    json序列化,就是将对象转换成json格式,或json格式转换成对象,例如把一个Student对象转换为json字符串{"name":"lisi","age":29},反序列化,将json格式的字符串转换{"name":"lisi","age":29}转换成Student对象

  5. image-20220113173851104

第7章 springboot集成dubbo

实现步骤

公共项目

  1. 独立的maven项目,定义了接口和数据类

  2. 创建接口module

    因为我们打包jar包,只需要打包这个接口module的jar包即可,把这个jar包添加到服务消费者module去,可知服务消费者方,并没有方法的具体实现,但是仍然能够像调用自己的方法一样调用远程服务提供方的实现的方法,这就是远程调用,是RPC的实现。底层是基于的动态代理的方式,创建代理对象,代理对象调用接口的方法就像调用实现类的方法一样,因为底层网络通信的细节对使用人员透明,是通过动态代理,我们把接口jar包加载到服务消费者方去,就是为了创建这个接口的代理对象!!

服务提供者项目

  1. 创建服务提供者即服务的实现module

    • 引入接口项目的依赖,目的是为了实现这个接口的方法,那么必须实现这个接口,所以必须要引入依赖,服务的提供者才会有接口方法的具体实现。

      后面在消费者module同样要引入这个接口项目的依赖,相当于之前学spring整合dubbo的时候,将接口项目打包(此jar包里只有接口和实体类,没有方法的具体实现),打好的jar包加载进消费者方,消费者方需要此接口jar包的目的是创建接口的对象,实际是代理对象,因为dubbo的底层是动态代理,而动态代理的底层是反射机制。

              <!--引入公共依赖项-->
              <!--加入公共项的gav-->
              <dependency>
                  <groupId>org.example</groupId>
                  <artifactId>springboot-dubbo-interface</artifactId>
                  <version>1.0-SNAPSHOT</version>
              </dependency>
      
    • 加入dubbo依赖

              <!--加入dubbo的依赖-->
              <dependency>
                  <groupId>org.apache.dubbo</groupId>
                  <artifactId>dubbo-spring-boot-starter</artifactId>
                  <version>2.7.8</version>
              </dependency>
      
    • 加入注册中心zookeeper的依赖

              <!--加入zookeeper依赖-->
              <dependency>
                  <groupId>org.apache.dubbo</groupId>
                  <artifactId>dubbo-dependencies-zookeeper</artifactId>
                  <version>2.7.8</version>
                  <type>pom</type>
              </dependency>
      
    • 写一个接口的实现类,实现接口里的方法

      /**
       * 使用dubbo中的注解暴露服务
       */
      @DubboService(interfaceClass = StudentService.class, version = "1.0", timeout = 5000)
      public class StudentServiceImpl implements StudentService {
          @Override
          public Student queryStudent(Integer id) {
              Student student = new Student();
              if (1001 == id) {
                  student.setId(1001);
                  student.setName("张三");
                  student.setAge(20);
              } else if (1002 == id) {
                  student.setId(1002);
                  student.setName("李四");
                  student.setAge(22);
              }
              return student;
          }
      }
      
    • 暴露服务

      /**
       * 使用dubbo中的注解暴露服务
       */
      @DubboService(interfaceClass = StudentService.class, version = "1.0", timeout = 5000)
      
    • 配置服务名称、dubbo协议和端口、注册中心

      #配置服务名称 类似于之前在spring配置文件里写标签<dubbo:application name="名称">
      spring.application.name=studentservice-provider
      
      #配置扫描的包,扫描@DubboService注解
      dubbo.scan.base-packages=com.example.service
      
      #原先在spring配置文件里配那些,现在用了springboot,都在application.properties/yml配置文件里写。
      #配置dubbo协议
      #dubbo.protocol.name=dubbo
      #dubbo.protocol.port=20881
      
      ## 注册中心
      dubbo.registry.address=zookeeper://localhost:2181
      

      注意使用springboot集成dubbo,暴露服务接口并不在配置文件里写了,而是通过注解的方式写在服务接口的实现类上。

    • 在启动类上加入@EnableDubbo注解

    • 启动服务提供者项目,发现会报错

      SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]
      Exception in thread "main" java.lang.IllegalArgumentException: LoggerFactory is not a Logback LoggerContext but Logback is on the classpath. Either remove Logback or the competing implementation (class org.slf4j.impl.Log4jLoggerFactory loaded from file:/D:/installations/maven/apache-maven-3.8.1/maven-repository/org/slf4j/slf4j-log4j12/1.7.30/slf4j-log4j12-1.7.30.jar). If you are using WebLogic you will need to add 'org.slf4j' to prefer-application-packages in WEB-INF/weblogic.xml: org.slf4j.impl.Log4jLoggerFactory
      	at org.springframework.util.Assert.instanceCheckFailed(Assert.java:702)
      	at org.springframework.util.Assert.isInstanceOf(Assert.java:621)
      	at ...
      

      原因:在当前程序中,log4j这个jar包被加载多次,zookeeper的依赖重复加了log4j的依赖

      需要做排除

              <!--加入zookeeper依赖-->
              <dependency>
                  <groupId>org.apache.dubbo</groupId>
                  <artifactId>dubbo-dependencies-zookeeper</artifactId>
                  <version>2.7.8</version>
                  <type>pom</type>
                  <exclusions>
                      <exclusion>
                          <groupId>org.slf4j</groupId>
                          <artifactId>slf4j-log4j12</artifactId>
                      </exclusion>
                  </exclusions>
              </dependency>
      

服务消费者项目

  1. 创建服务消费者module

    • 添加公共接口jar包依赖

    • 添加dubbo依赖

    • 添加zookeeper依赖,并对重复加载的log4j做排除exclusion

    • 创建一个类来远程调用服务提供者的服务,通过@DubboReference注解创建接口的代理对象

          @DubboReference(interfaceClass = StudentService.class, version = "1.0")
          private StudentService studentService;
      

      image-20220114165603471

      创建的接口的对象(实际是代理对象,因为dubbo底层是动态代理)

      通过此对象调用方法,就像调用自己的方法一样,底层网络通信细节对使用者透明,dubbo是基于RPC的框架

      @RestController
      public class DubboController {
      
          /**
          @DubboReference 引用远程服务,把创建好的代理对象注入给studentService
          */
          @DubboReference(interfaceClass = StudentService.class, version = "1.0")
          private StudentService studentService;
      
          @GetMapping("/query")
          public String queryStudent() {
              Student student = studentService.queryStudent(1001);
              return student.toString();
          }
      }
      
    • 配置服务名称、注册中心

      ## 指定服务名称
      spring.application.name=consumer-application
      
      #指定注册中心
      spring.registry.address=zookeeper://localhost:2181
      
  2. 注意:在实际项目中,这里说的mudule其实是一个个单独的项目

第8章 springboot项目打包

概述

  1. 打包为web项目,是war文件

    普通Java项目,是jar文件

    springboot项目可以打包成war包和jar包两种方式

打包为war包

  1. pom.xml文件里的build标签,写打包后的文件名称

        <build>
            <!--打包后的文件名称-->
            <finalName>myboot</finalName>
            <!--
            让项目在编译的时候,扫描到指定目录下的指定格式的文件,编译完成后,这些文件会在类路径下,也就是target/class路径下
            类路径就是classpath:来表示。
            -->
            <resources>
                <resource>
                    <directory>src/main/webapp</directory>
                    <!--这是指定要编译到的指定目录-->
                    <targetPath>META-INF/resources</targetPath>
                    <includes>
                        <include>**/*.*</include>
                    </includes>
                </resource>
                <resource>
                    <directory>src/main/resources</directory>
                    <includes>
                        <include>**/*.*</include>
                    </includes>
                </resource>
            </resources>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
  2. 主启动类继承SpringBootServletInitializer

    SpringBootServletInitializer就是原有的web.xml文件的替代,使用了嵌入式servlet,默认是不支持jsp

    /**
     * 继承SpringBootServletInitializer这个类,才能使用独立的tomcat服务器
     */
    @SpringBootApplication
    public class SpringWarApplication extends SpringBootServletInitializer {
    
        public static void main(String[] args) {
            SpringApplication.run(SpringWarApplication.class, args);
        }
    
        @Override
        protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
            return builder.sources(SpringWarApplication.class);
        }
    }
    
  3. 在pom文件里指定打包类型为war包

    <packaging>war</packaging>
    
  4. 打包好的war文件就可以部署在单独的tomcat容器中(webapps目录中),进行启动,然后访问,效果和springboot启动项目是一样的,只不过springboot是内嵌的tomcat容器,同时我们也可以将这个war包通过IDEA的maven web项目,进行发布、部署。

    如图,选择External Source

    image-20220114181707180

打包为jar包

  1. 在pom.xml文件里的build标签,通过finalName标签指定打包后的文件名称

        <build>
            <!--打包后的文件名称-->
            <finalName>myboot</finalName>
    
  2. 默认是打包为jar包,所以不需要通过<packaging>jar</packaging>声明

  3. 执行maven clean、package

    在target目录中,会生成jar文件。

  4. jar包的执行方式:

    • 在jar包目录下,打开命令行,执行java -jar myboot.jar

      这就是独立启动jar包。

jar包和war包的区别

  1. 打包war包,需要有服务器才能执行,是将打包的war包部署到这个服务器。

    jar包可以独立运行,不依赖于tomcat,简单轻巧

    jar包里有内嵌的tomcat

    部署jar包更方便

第9章 模板引擎Thymeleaf

概述

  1. thymeleaf是一个流行的模板引擎,该模板引擎采用Java语言开发。

  2. thymeleaf对网络环境不存在严格的要求,既可以用于web环境下,也能用于非web环境下,在非web环境下,他能直接显示模板上的静态数据;在web环境下,它能像jsp一样从后台接收数据并替换掉模板上的静态数据。

    thymeleaf是基于html的,以html标签为载体,thymeleaf要寄托在html标签下实现。

  3. springboot集成了thymeleaf技术,并且springboot官方也推荐使用thymeleaf来替代jsp技术,作为前端页面的数据展示。

  4. jsp是完成页面的动态渲染,是需要编译运行,效率低。

  5. 什么叫模板呢?

    image-20220114195307270

    这里添加了数据,放在了request作用域。

    SpringMVC中要完成对请求的处理并对结果的展示大致会经历以下过程(不细说):

    处理器映射器,处理器执行链,处理器适配器,Controller中的方法,视图解析器对象,视图对象(View对象)。

    视图对象就负责对数据的前端展示。

    在页面中,通过以下EL表达式,拿到数据并展示。

    image-20220114195521639

    在$这个位置上,相当于占位符,在这个位置会获得request作用域中实际的数据,实际上jsp就是一个模板技术。

    jsp是最早的一种模板技术,数据来自服务器端。

    只不过jsp是局限于Java语言的。

    模板引擎就是做视图处理的,jsp就可以理解为是一种很早的模板引擎。

  6. Java生态下的模板引擎有Thymeleaf,Freemaker,Velocity等,都是视图层的,做数据显示的,他们的作用都是等同于jsp的。

  7. 模板引擎是运行在服务器端的,所以可以说是动态的,jsp也是运行在服务器端的,是动态的。

    html才是静态的。动态的有对数据的处理能力。

    jsp页面最终也会翻译成html页面。

  8. 可以简单把模板技术理解为对字符串的替换!

使用

  1. 当html页面中,没有写thymeleaf相关语句的时候,显示的就是静态数据。

    如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>hello.html</title>
    </head>
    <body>
        <h3>使用thymeleaf的例子</h3>
        <p>想显示数据</p>
    </body>
    </html>
    

    image-20220114215634437

    在非web环境下,他能直接显示模板上的静态数据;在web环境下,它能像jsp一样从后台接收数据并替换掉模板上的静态数据。

    如果写了thymeleaf相关语句,显示从后台即服务程序中接收到的数据。如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>hello.html</title>
    </head>
    <body>
        <h3>使用thymeleaf的例子</h3>
        <p th:text="${data}">想显示数据</p>
    </body>
    </html>
    

    image-20220114215743231

    如上的th:text="${data}"就是模板中的语法,意思是取出data域的数据并替换后面的静态文本。

    data域的数据是来自后台程序,如下:

    @Controller
    public class HelloThymeleafController {
        @GetMapping("/hello")
        public String helloThymeleaf(Model model) {
            //添加数据到request作用域,或者使用ModelAndView或者Model,都会最终将数据放入request作用域
            //模板引擎可以用从request中获取数据
            model.addAttribute("data", "欢迎使用thymeleaf模板引擎1111");
    
            //指定视图,之前是jsp,现在是指定模板引擎所使用的页面(基于html标签,所以是html)
            //逻辑名称
            return "hello";
        }
    }
    
  2. thymeleaf起步依赖

            <!--模板引擎起步依赖-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-thymeleaf</artifactId>
            </dependency>
    
  3. 在application.properties/yml中进行配置

    ## 在开发阶段,关闭模板缓存,让修改立即生效
    spring.thymeleaf.cache=false
    
    ## 以下配置是默认的。
    ## 编码格式
    spring.thymeleaf.encoding=utf-8
    
    ## 也就是说模板是html文件
    spring.thymeleaf.mode=HTML
    
    ## 模板引擎默认存放路径,即模板的前缀,结合前缀和后缀,所以在controller中,直接return hello
    ## 和视图解析器是一样的。
    spring.thymeleaf.prefix=classpath:/templates/
    spring.thymeleaf.suffix=.html
    

thymeleaf语法

标准变量表达式

  1. 标准变量表达式

    表达式是在页面获取数据的一种thymeleaf语法,类似${key}

    image-20220114221736263

    使用request.setAttribute(),model.addAttribute()将返回结果放在request作用域中。

  2. image-20220114224001635

    ${}是相当于占位符,会把从request域中取到的内容替换到右边的文本位置!!

    如果不写thymeleaf表达式,那么会显示右边的文本,如果写了,但是request里并没有这个字段,那么会取到一个空值,这个空值仍然会替换右边的文本

选择变量表达式

  1. 语法:*{key} 说明:需要配合 th:object 一起使用。选择变量表达式,也叫星号变量表达式,使用 th:object 属 性来绑定对象,选择表达式首先使用 th:object 来绑定后台传来的对象,然后使用 * 来代表这 个对象,后面 {} 中的值是此对象中的属性。 选择变量表达式 *{...} 是另一种类似于标准变量表达式 ${...} 表示变量的方法 选择变量表达式在执行时是在选择的对象上求解,而${...}是在上下文的变量 model 上求解

    目的是简化获取对象属性值。

  2. 示例:

    image-20220114224606159

链接表达式

  1. 语法:@{链接 url}

    说明:主要用于链接、地址的展示,可用于<script src="...">、<link href="...">、<a href="...">、<form action="...">、<img src="">等,可以在 URL 路径中动态获取数据
    
  2. 传参

    image-20220114225619386

    image-20220114230144044

属性

  1. 属性是放在html元素中的,就是html元素的属性,加了th前缀,属性的作用不变,加上了th,属性的值就由模板引擎处理了,在属性可以就使用thymeleaf变量表达式。

注解总结:

spring+springMVC+springboot

创建对象的注解

  1. @Controller

    放在类的上面,创建控制器对象并注入到容器中

  2. @RestController

    放在类的上面,创建控制器对象并注入到容器中

    是一个复合注解,是@Controller + @ResponseBody的复合注解

    使用这个注解的控制类,里面的方法的返回值都是数据

  3. @Service

    放在业务层实现类的上面,创建Service对象,注入到容器

  4. @Repository

    放在dao层的实现类的上面,创建dao对象,放入到容器中。

    现在很少使用这个注解,是因为我们使用mybatis框架,而dao对象是mybatis通过动态代理生成的对象。

    我们使用mybatis,都不需要写dao接口的实现类,所以不需要在实现类上面去加这个注解。dao对象是由mybatis自动生成

  5. @Component

    是放在类的上面,表示创建此类的对象,并注入到容器中。和三层架构分层没有关系,就表示创建对象。

    如果对象不是三层中的任何一层,就用这个注解来创建对象并放入到容器是很合适的。

赋值的注解

  1. @Value

    简单类型的赋值,例如在属性的上面使用

    @Value("李四")
    private String name;
    

    还可以使用@Value,获取配置文件的数据,这里的配置文件是说springboot中的application.properties/yml

    @Value("${server.port}")
    private Integer port;
    
  2. @Autowired

    给引用类型变量赋值自动注入的,支持byName、byType,默认是byType的,放在属性的上面,也可以放在构造方法的上面。

    @Qualifier:给应用类型赋值,使用byName方式

    以上两个注解都是来自spring框架的。

  3. @Resource

    给引用类型变量赋值自动注入的,支持byName、byType,默认是byName的,如果通过byName自动注入失败,会采用byType的方式对引用类型变量赋值。

    是JDK中的定义。放在属性的上面

其他注解

  1. @Configuration

    放在类的上面,表示这是个配置类,相当于配置文件的作用,这里的配置文件是指spring和springmvc的xml配置文件

  2. @Bean

    放在方法的上面,把方法的返回值对象,注入到spring容器中

  3. @ImportResource

    加载其他的xml配置文件,把文件中的对象,注入到spring容器中

  4. @PropertyResource

    读取其他的属性配置文件,可以指定要读取的配置文件在类路径下的位置。

    通过${key}可以读到配置文件中的值。

  5. @ComponentScan

    扫描器,指定包名,扫描注解,把写了对应注解的类的对象都注入到容器中。

    相当于XML配置文件中的组件扫描器

  6. @ResponseBody

    放在方法的上面,表示方法的返回值是数据,不是视图

  7. @RequestBody

    把请求体中的数据,读取出来,转为Java对象使用

  8. @ControllerAdvice

    控制器增强,放在类的上面,表示此类提供了一些方法,可以对Controller增强功能。

  9. @ExceptionHandler

    用来处理异常的,放在方法的上面

    和@ControllerAdvice经常是一起搭配使用,@ControllerAdvice是写在自定义异常类的上面。

  10. @Transactional

    处理事务的,放在service实现类的public方法上面,表示此方法有事务。

springboot中的注解

  1. @SpringBootConfiguration

    放在启动类之上的,包含了以下三个注解的功能

    @SpringBootConfiguration---表示这是一个配置类

    @EnableAutoConfiguration---自动配置功能

    @ComponentScan---扫描器

mybatis相关的注解

  1. @Mapper

    放在接口的上面,让mybatis找到这个接口,并创建它的代理对象。

  2. @MapperScan

    和@Mapper一样,是让mybatis找到dao接口,并创建dao接口的代理对象。

    这种方式只需要在主启动类上加上@MapperScan注解,并指定dao接口所在的包名。

  3. @Param

    放在dao接口的方法的形参前面,作为命名参数使用的。

dubbo相关的注解

  1. @DubboService

    在提供者端使用的,是暴露dubbo服务的,是放在接口的实现类上面的。

  2. @DubboReference

    在消费者端使用的,引用远程服务的,放在属性上面使用,这个属性是dubbo创建的接口的代理对象

    通过此代理对象就能够像调用自己的方法一样,调用远程服务,即使消费者端并没有方法的实现,方法的实现在服务提供者的实现类里面。

  3. @EnableDubbo

    放在主类上面,表示当前引用启用Dubbo功能

Last Updated:
Contributors: 陈杨