【SpringBoot】一、SpringBoot概述以及其自动配置基本原理

SpringBoot

SpringBoot现在分为两个技术栈,第一个是常规的使用servletAPI的Web编程方式,第二种是使用Reactive方式的响应式编程,Reactive Stack可以使用很少的内存来实现复杂的功能,提升性能并压缩成本,是一种很好的新型方式

SpringBoot优点

  • 创建一个完整的、独立的Spring应用
  • 内嵌独立的Tomcat服务器,不需要再进行其他配置
  • 自动处理依赖关系,不需要自己进行依赖管理
  • 自动配置spring以及第三方功能
  • 自动进行生产级别的健康监控
  • 无代码生成,不会因为一次一次的运行添加过多的代码

SpringBoot特点就是使用微服务构建出一个个的独立的模块,再用这些独立出来的模块进行分布式开发,分布式所涉及的问题可以由Spring Cloud进行解决,而产生的数据流也可以使用Spring Cloud Data Flow处理

使用SpringBoot的一个Demo

  • 需要先创建一个maven项目并在项目的pom.xml文件中声明父工程:

在pom.xml文件中:

需要联网并下载依赖文件

    <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>2.3.4.RELEASEversion>
    parent>
  • 只需要导入web场景启动器依赖就可以,不用其他复杂依赖

    这个依赖中包括日志、springmvc等所有需要的依赖

    <dependencies>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
    dependencies>
  • 进行主类启动器的编写:
/**
 * @SpringBootApplication注解
 * 用来标识这是一个SpringBoot应用
 * 这个类是一个固定写法,作为springboot启动器
 */
@SpringBootApplication
public class MainApplication {
    //固定写法
    public static void main(String[] args) {
        //参数为这个类的Class对象
        SpringApplication.run(MainApplication.class);
    }
}
  • 进行Controller层的编写
/**
 * @ResponseBody注解用于标识所有的Return值是写给浏览器的,而不是代表跳转
 */
//@ResponseBody
//@Controller

/**
 * @RestController注解代表@Controller注解与@ResponseBody注解的合体
 * 是需要同时用到两个注解时的简单写法
 */
@RestController
public class HelloController {
    @RequestMapping("/Hello")
    public String handle01() {
        return "Hello SpringBoot2!";
    }
}

所有的SpringBoot的配置都集成在application.properties文件中

例如端口号的修改只需要在Application.properties中添加server.port=新端口号即可

server.port=8888

另外,在简化pom.xml文件中加入构建项目的依赖:


    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
            plugin>
        plugins>
    build>

这样在cmd的 java -jar命令下就可以直接在cmd的环境下运行这个项目

注意:在springboot环境下,所有的项目都是由父工程springboot进行统一管理的。

若需要某些依赖固定一些版本的话,则需要在pom.xml文件中添加properties标签并加入对应依赖属性,例如mysql版本的改变

<properties>
    <mysql.version>5.1.43mysql.version>
properties>

记得在springboot依赖中找到对应的依赖的key属性

springboot是基于主程序所在的包进行包扫描的,所有与主程序在同一个包下的注解都会被扫描,但也可以进行扩大,只要在@SpringBootApplication的scanBasePackages属性下声明好就可以将扫描的包路径扩大。

SpringBoot的自动配置也是按需加载的,不会把所有的配置都加载,而是会在配置了对应的启动配置之后才会生效。

SpringBoot的配置文件

@Configuration注解用来标识一个类为配置类,Spring会寻找这个注解并将这个注解下的类中的方法视作创建对象,例如IoC中,对于对象的依赖注入就可以下面这么写:

在boot文件夹下创建配置类的存放文件夹config并创建一个类:MyConfig.java

//@Configuration注解,用来标识一个类,作用是进行配置,让SpringBoot来进行扫描时以配置类的眼光来看这个类以及其下的方法
@Configuration
public class MyConfig {

    @Bean       //进行注入的注解,标识一个方法表示这个方法的返回值作为要返回的对象,返回值类型作为要创建的对象类型,方法名作为对象的id属性
    public User user01() {
        return new User("ZhangGeGe", 18);
    }

    //或者在Bean注解中添加一个value,则组件名后面就叫这个value的属性值,不会再叫方法名了。
    @Bean("Tom")
    public Pet cat() {
        return new Pet("Tomcat");
    }
}

验证配置:

在主类中通过循环获取所有的组件名称后可以看到有user01和Tom出现

    public static void main(String[] args) {
        //参数为这个类的Class对象
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class);

        //查看容器内组件
        String[] names = run.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }
    }

并且是通过单例模式进行创建,因此会相等:

        //查看容器内组件
        String[] names = run.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }

        Pet tom = run.getBean("Tom", Pet.class);

        Pet tom1 = run.getBean("Tom", Pet.class);

        System.out.println("组件:" + (tom == tom1));

此外:@Configuration还有一个proxyBeanMethods属性:

该属性:

//proxyBeanMethods属性代表其是否使用代理,使用代理则其为单例模式,每一个类只有一个对象,false则在每次调用的时候都会新创建一个对象
@Configuration(proxyBeanMethods = true)
        //从容器中获取对象
        User user = bean.user01();
        User user1 = bean.user01();
        System.out.println("是否是一个:" + (user == user1));

简而言之:

  • 不需要组件之间有依赖关系,允许多个实例时使用Lite模式(proxyBeanMethods = false),关闭它就不会检查容器中是否已有
  • 需要依赖关系时使用Full模式(proxyBeanMethods = true)

@Import

@Import注解用于标注组件,并向容器中注入对象,这种方式注入的对象组件名叫做全类名,且会与@Bean注解注入的方式注入不同的对象,也就是说在容器中会存在两个组件

//Import组件,其形参是一个Class型的数据,只要在其中声明了,就会在容器中创建对应的对象
@Import({User.class, DBHelper.class})

@Conditional

Conditional组件用来标注类或者方法,只有当Conditional组件中内容成立时才会执行其所标注的语句

例如ConditionalOnBean注解标注时,只有当容器中有某个组件,下面语句才生效

@ConditionalOnBean(name = "Tom")

再录入@ConditionalOnMissingBean就代表容器中没有某个组件时才令下面的语句生效

@ImportResource

若有之前的第三方插件使用配置文件的方式进行文件配置时,可以在Config类上添加@ImportResource注解来将配置文件中的对象注入到容器中。

@ImportResource("classpath:bean.xml")

之后在容器中进行操作时就可以使用run.getBean(String)方法来获取组件。

@ConfigurationProperties 配置绑定

SpringBoot还提供了在配置文件中进行容器中组件的属性配置功能,在配置文件中以xxx.属性的方式进行配置,并在类上标识@ConfigurationProperties注解以及@Component注解来保证其存在于容器中,就可以进行属性配置,例如:

Application.proprties:

mycar.brand=BYD
mycar.price=100000

要绑定的类:

@Component
//.前面的要相等
@ConfigurationProperties(prefix = "mycar")
public class Car {
    private String brand;
    private Integer price;

另外,也可以使用@EnableConfigurationProperties注解来将指定的类来注入容器中,这个注解可以视作在Car类上标注了@Component注解,将这个类的对象组件直接加入容器。

@EnableConfigurationProperties(Car.class)

注意就算用了Enable这个注解,@ConfigurationProperties(prefix = “mycar”)这个注解也还是要写。

源码解析

@SpringBootApplication注解:

该注解相当于三个注解合起来:

@SpringBootConfiguration

@EnableAutoConfiguration

@ComponentScan(“要扫描的包名”)

  • @SpringBootConfiguration底层中是一个@Configuration注解,标注Main类也是一个配置类的组件,主要作用是将其标注为启动类
  • @ComponentScan(“要扫描的包名”)指定要扫描的包的路径,指明哪些包需要扫描
  • @EnableAutoConfiguration中又是由@AutoConfigurationPackage组成的,这个注解标注了组件的注册,注册的地址是Main类所在的路径,故而我们的组件是从Main所在的文件夹决定的。

另外,@EnableAutoConfiguration注解也由@Import注解组成,该注解决定了SpringBoot在启动时加载所有的自动配置类,但只有在对应的配置需要开启时(有对应的组件导入时)才开启。(默认全部开启装载,但按需配置)

若使用@Bean注解的方法有形参传入,则传入的形参会自动从容器中找

关于配置与Application.Properties的绑定

所有的配置都会有一个xxxxAutoConfiguration类,这个类都会有一个@EnableConfigurationProperties注解,这个注解决定了自动配置需要的类,而这个类上一般会有@ConfigurationProperties注解,这个注解的prefix属性就决定了我们要在Application.properties文件中配置的属性的开头是哪些

你可能感兴趣的:(SpringBoot,spring,boot,java,spring)