【SpringBoot2】 SpringBoot2核心技术 基础

写在前面

1 SpringBoot2核心技术 基础

1.1 Spring与SpringBoot

SpringBoot是一个高层框架

1.2 项目创建

1.2.1 创建POM

①导入spring-boot-starter-parent父工程

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

②添加依赖spring-boot-starter-webSpringBootWeb场景启动器,会自动进行导入web场景所用的jar包

pom.xml

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.hikaru</groupId>
    <artifactId>SpringBoot_HelloWorld</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

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

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
</project>
1.2.2 创建主程序
@SpringBootApplication
public class MainApplication {
    public static void main(String[] args) {
        SpringApplication.run(MainApplication.class, args);
    }
}

MainApplication为主程序类,@SpringBootApplication注解表明这是一个SpringBoot应用。

1.2.3 编写业务

主程序类MainApplication默认只会访问同一包下的文件,所以编写的业务类应该和主程序类放在同一个包下!

@RestController
public class HelloController {

    @RequestMapping("/")
    public String hello() {
        return "Hello,boot!";
    }
}

@ RestController注解为 @ ResponseBody 和 @ Controller 的合体

1.2.4 /resources/Application.properties指定Tomcat服务器端口号

application.properties

server.port=8081

SpringBoot内置了Tomcat服务器,不再需要手动进行配置

文件名固定且区分大小写,否则IDEA中能够读取(但是文件中变量为灰色表示没有被用到)但是打成的jar包无法读取配置信息

1.3 项目部署

以前部署的做法,是将项目打包成war,然后在服务器安装tomcat,再将war部署到tomcat服务器。而现在,SpringBoot可以通过引入一个spring-boot-maven-plugin插件将项目打包成为一个可以执行的jar包。

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.7.2</version>
            </plugin>
        </plugins>
    </build>

1.4 项目配置的原理

依赖管理spring-boot-starter-parent中

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

它的父项目spring-boot-dependencies几乎声明了开发中常用的依赖版本号,因此在开发中引入依赖无需关注版本号,即自动仲裁

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

而且也可以根据开发中的需求进行修改版本号:首先在spring-boot-dependencies查看依赖的版本定义,然后在spring-boot-starter-parent中进行修改。

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>

        <mysql-version>5.1.43</mysql-version>
    </properties>

1.5 场景启动器

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

形如spring-boot-starter-***,即为Spring-boot场景启动器,只要引入starter,这个场景的所有常规需要的依赖我们都自动引入,Spring Boot所有支持的场景:

可以在项目pom.xml下右键生成分析依赖树:

场景启动器最底层的依赖:

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
      <version>2.7.2</version>
      <scope>compile</scope>
    </dependency>

1.6 自动配置

1.6.1 自动配置tomcat

①引入tomcat依赖

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-tomcat</artifactId>
      <version>2.7.2</version>
      <scope>compile</scope>
    </dependency>
1.6.2 自动配置Spring-MVC

①引入MVC全套组件

如DispatcherServlet用于拦截所有请求、字符编码拦截器CharacterEncodingFilter用于解决返回响应中文乱码问题、viewResolver视图解析器、文件上传解析器multipartResolve

②自动配置好SpringMVC常用组件(功能)

1.6.3 自动配置web常见功能

如上面说的字符编码问题

1.6.4 默认的包结构

主程序所在的包其下面的包里面的组件都会被默认扫描出来,无需配置以前的包扫描。同时也可以自行指定扫描的包。

①通过SpringBootApplication注解的属性值scanBasePackages指定

@SpringBootApplication(scanBasePackages = "com.hikaru.boot")

②通过使用ComponentScan包扫描注解

③通过三个混合注解,等同于SpringBootApplication+属性值的方式

@SpringBootConfiguration
        @EnableAutoConfiguration
        @ComponentScan

1.6.5 配置的默认值

默认配置都会最终映射到一个配置文件,如spring.servlet.multipart.max-file-size即上传文件的文件最大值设定最终会映射MultipartProperties。

然后配置文件的值会映射到对应的类中,如MultipartProperties类,最终带着配置信息在IOC容器中创建对象。

1.6.6 按需加载所有的自动配置项

引入哪些场景,那些场景的自动配置才会进行。SpringBoot的所有自动配置功能都在spring-boot-autoconfigure中。如spring-boot-starter-web场景依赖spring-boot-starterspring-boot-autoconfigure包就存在于其中。

2 容器注解

2.1 @Configuration注解

@Configuration注解 + @Bean的方式进行组件注册,详细可以参照之前的博文:【Spring注解驱动】(一)IOC容器 - Tod4 - 博客园

@Bean注册的组件默认是单实例的(@Bean的单例、多例可以由@Scope注解进行控制),@Configuration的配置类也是一个组件,而且这个组件默认是一个代理对象,即这个对象负责进行其他组件的实例化。

2.1.1 Lite 模式

而在SpringBoot中,@Configuration进行了部分修改,增加了属性proxyBeanMethods,属性值为true时,表示经过代理对象创建的组件默认为单实例,为false则为多实例。

@Configuration(proxyBeanMethods = true)
public class MyConfig {
    @Bean
    public User user() {
        return new User(1, "ryuu", "123");
    }
    @Bean
    public Pet tomCat() {
        return new Pet("Tom");
    }
}

进行测试,第一个为true,第二个为false,这是因为:第二个是通过代理对象调用方法,创建的因此需要服从proxyBeanMethods参数的设定,SpringBoot在方法执行的时候总会先行检查IOC容器中是否存在该组件,如果存在则直接返回而不会去重新创建,以此实现单例模式;而第一个不用,而且此时输出bean则会显示:com.hikaru.boot.config.MyConfig$$EnhancerBySpringCGLIB$$14aea548@4565a70a,表明这个是一个代理对象

@SpringBootApplication(scanBasePackages = "com.hikaru.boot")
public class MainApplication {
    public static void main(String[] args) {
        // 返回IOC容器
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
        User user1 = (User) run.getBean("user");
        User user2 = (User) run.getBean("user");
        System.out.println(user1 == user2);

        MyConfig bean = run.getBean(MyConfig.class);
        User user3 = bean.user();
        User user4 = bean.user();
        System.out.println(user3 == user4);
    }
}

Lite模式的应用场景大多是在组件依赖中,即一个类中包含着子类,实例化的时候能够保证子类的实例化对象和IOC容器中的是同一个。

2.1.2 Full 模式

若将参数改为false(默认为true),则输出bean为com.hikaru.boot.config.MyConfig@378bd86d是一个真正的对象,而不需要进行代理,创建的对象自然也不是单例的。

2.2 @Conditional注解实现按条件注册

正常的使用方法是声明一个Condition的实现类作为注解的value值,并实现其matches方法在其中写好条件逻辑,以判断注解所在的类是否满足条件注册,这里不再赘述。

SpringBoot则在此基础上新增了大量不同场景的注解,如@ConditionalBean表示容器存在其他Bean则注册此Bean。

2.3 @ImportSource导入原生配置文件

为了防止原生的配置文件如xml手动转换为注解方式过于繁琐,可以在相关配置类上添加@ImportSource注解即可将配置Bean导入配置类。

2.4 ConfigurationProperties配置绑定

回忆一下之前Property配置文件绑定的方法,是通过

  • 在类上添加 @PropertySource 注解,然后通过 @Value('${环境变量名}') 的方式

  • 或者直接在容器中:

        ConfigurableEnvironment environment = context.getEnvironment();
        String property = environment.getProperty("环境变量名");

2.4.1 @ConfigurationProperties 绑定组件和配置文件

而在SpringBoot中,则可以使用下面的方式,使得组件可以从SpringBoot配置文件application.properties中绑定以mycar为开头的变量,并在容器自动装配的时候进行属性赋值。

@ConfigurationProperties(prefix = "mycar")
@Component
public class Car

application.properties

server.port=8080

mycar.carName = BYD

mycar.carPrice = 1000000

这种方式只能适用于容器中的组件

2.4.2 @EnableConfigurationProperties

也可以使用下面的方式进行配置绑定,@EnableConfigurationProperties有两个功能:

  • 开启组件的配置绑定

  • 在容器中注册该组件

简而言之,@EnableConfigurationProperties + @ConfigurationProperties = @ConfigurationProperties + @Component

@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(Car.class)
public class MyConfig

3 自动配置原理入门

源码先略过了。。

3.1 引导加载自动配置类

3.1.1 SpringBootConfiguration

4 最佳实践

4.1 SpringBoot如何编写

如设置Spring启动的banner图,直接在application.properties添加

spring.banner.image.location = classpath:banner.png

4.1 Lombok简化JavaBean开发

  • 引入lombok依赖,SpringBoot对其自动版本仲裁,在spring-boot-dependencies中可以看到信息。
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
  • 搜索安装lombok插件,新版idea已经自动集成了

  • 在Bean上添加@Data注解,即可在编译的时候自动生成gettersetter方法

  • 在 Bean上添加@toString注解,即可在编译的时候自动生成toString方法

  • 在 Bean上添加AllArgsConstructor注解,即可在编译的时候自动生成有参构造器

  • 在 Bean上添加NoArgsConstructor注解,即可在编译的时候自动生成无参构造器

  • 在类上添加@Slf4j注解,然后可以在类方法中使用log打印日志信息

4.2 devtools热部署

  • 引入devtools依赖

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
            </dependency>
    
  • ctrl+f9,如果是对静态文件的修改可以不经过重启服务器直接run,否则会进行服务器重启

4.3 SpringInitializer

可以在创建的时候选择场景启动器和版本,生成配置文件和容器启动器。使得我们只需要关注业务逻辑的编写。

posted @ 2022-08-02 17:32  Tod4  阅读(59)  评论(0编辑  收藏  举报