0
点赞
收藏
分享

微信扫一扫

SpringBoot2核心技术篇(自动配置原理入门[一])

1.SpringBoot特点

1.1依赖管理

  • 父项目做依赖管理

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

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

  • 开发导入starter场景启动器

1、见到很多 spring-boot-starter-* : *就某种场景
2、只要引入starter,这个场景的所有常规需要的依赖我们都自动引入
3、SpringBoot所有支持的场景
https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-starter
4、见到的  *-spring-boot-starter: 第三方为我们提供的简化开发的场景启动器。
5、所有场景启动器最底层的依赖
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter</artifactId>
  <version>2.3.4.RELEASE</version>
  <scope>compile</scope>
</dependency>

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

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

  • 可以修改版本号
    若是想独立的修改某个依赖的版本,比如mysql,便可以如此修改,自定义修改版本

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

1.2自动配置

  • 自动配好Tomcat
  • 引入Tomcat依赖
  • 配置Tomcat

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

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

@SpringBootApplication
等同于
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("com.atguigu.boot")

  • 各种配置拥有默认值
  • 默认配置最终都是映射到某个类上,如:MultipartProperties
  • 配置文件的值最终会绑定每个类上,这个类会在容器中创建对象
  • 按需加载所有自动配置项
  • 非常多的starter
  • 引入了哪些场景这个场景的自动配置才会开启
  • SpringBoot所有的自动配置功能都在 spring-boot-autoconfigure 包里面

2.容器功能

2.1组件添加

1.@Configuration
  • 基本使用
  • Full模式与Lite模式
  • 示例
  • 最佳实战
  • 配置 类组件之间无依赖关系用Lite模式加速容器启动过程,减少判断
  • 配置类组件之间有依赖关系,方法会被调用得到之前单实例组件,用Full模式

对于以前的spring注入对象,我们需要的是大量的xml一一进行映射,而现在我们只需要一个配置类

/**
 * 配置类里面使用@Bean标注在方法上给容器注册组件,默认也是单实例的
 * 配置类本身也是组件
 * proxyBeanMethods: 代理bean的方法
 *        Full(proxyBeanMethods = true)、【保证每个@Bean方法被调用多少次返回的组件都是单实例的】
 *        Lite(proxyBeanMethods = false)【每个@Bean方法被调用多少次返回的组件都是新创建的】
 *        组件依赖必须使用Full模式默认。其他默认是否Lite模式
 */
@Configuration(proxyBeanMethods = true)  //告诉springBoot这是一个配置类 == 配置文件
public class MyConfig {

    /**
     * 外部无论对配置类中的这个组件注册方法调用多少次获取的都是之前注册容器中的单实例对象
     *
     * @return
     */
    @Bean //给容器中添加组件。以方法名作为组件的d。返回类型就是组件类型 返回的值,就是组件在容器中的实例
    public User user01() {
        User zhangsan = new User("zhangsan", "18");
        //user组件依赖了Pet组件
        zhangsan.setPet(TomCat());
        return zhangsan;
    }

    @Bean("tom")
    public Pet TomCat() {
        return new Pet("tomcat");
    }
}

实体类

public class Pet {
    private String name;

    public Pet() {
    }

    public Pet(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Pet{" +
                "name='" + name + '\'' +
                '}';
    }
}

public class User {
    private String name;
    private String gender;
    private Pet pet;
    public User() {
    }

    public User(String name, String gender) {
        this.name = name;
        this.gender = gender;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public Pet getPet() {
        return pet;
    }

    public void setPet(Pet pet) {
        this.pet = pet;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", pet=" + pet +
                '}';
    }
}

主程序类

/**
 * 主程序类
 *
 * @SpringBootApplication: 这是一个SpringBoot应用
 */
@SpringBootApplication
public class MainApplication {
    public static void main(String[] args) {

        //1.返回IOC容器
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
        //2.查看容器里的组件
        String[] names = run.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }

        //从容器中获取组件
        Pet tom01 = run.getBean("tom", Pet.class);
        Pet tom02 = run.getBean("tom", Pet.class);
        System.out.println("组件:" + (tom01 == tom02));

        //com.qz.boot.config.MyConfig$$EnhancerBySpringCGLIB$$954fcaca@1ec7d8b3
        MyConfig bean = run.getBean(MyConfig.class);
        System.out.println(bean);

        //如果Configuration(proxyBeanMethods=true)代理对象调用方法。SpringBoot总会检查这个组件是否在容器
        //保持组件单实例
        User user = bean.user01();
        User user1 = bean.user01();
        System.out.println(user == user1);


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

        System.out.println("用户的宠物:"+(user01.getPet() == tom));
    }
}

2.@Bean、@Component、@Controller、@Service、@Repository

这几个注解没什么好说的,学过spring的都知道

3.@ComponentScan、@Import

* @Import({User.class,DBHelper.class})
 *  给容器中自动创建出这两个类型的组件、默认组件的名字就是全类名
 */
@Import({User.class,DBHelper.class})
@Configuration(proxyBeanMethods = true)  //告诉springBoot这是一个配置类 == 配置文件
public class MyConfig {

//5、获取组件
String[] beanNamesForType = run.getBeanNamesForType(sen.class);
System.out.println("======");
for (String s : beanNamesForType) {
    System.out.println(s);
    DBHelper bean1 = run.getBean(DBHelper.class);
    System.out.println(bean1);
}

4.@Conditional

条件装配:满足Conditional指定的条件,则进行组件注入

SpringBoot2核心技术篇(自动配置原理入门[一])_springboot

2.2原生配置文件引入

@ImportResource

当我们写好了xml配置文件时,就可以使用这个注解,来让springboot生效

@ImportResource("classpath:beans.xml")
public class MyConfig {}

2.3配置绑定

如何使用Java读取到properties文件中的内容,并且把它封装到JavaBean中,以供随时使用;

第一种方式@ConfigurationProperties

把properties文件跟实体类的文件进行绑定,这种方式就需要把Car注册到Controller层需要加入Component注解

实体类

/**
 * 只有在容器中的组件,才会拥有SpringBoot提供的强大功能
 */
@Component
@ConfigurationProperties(prefix = "mycar")
public class Car {
    private String brand;
    private Integer price;

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public Integer getPrice() {
        return price;
    }

    public void setPrice(Integer price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Car{" +
                "brand='" + brand + '\'' +
                ", price=" + price +
                '}';
    }
}

propertis文件

mycar.brand=BMW
mycar.price=400000

Controller层

@RestController
public class HelloController {
    @Autowired
    Car car;

    @RequestMapping("/car")
    public Car car(){
        return car;
    }
}

第二种方式@EnableConfigurationProperties + @ConfigurationProperties

@EnableConfigurationProperties(Car.class)
/*
1.开启Car的配置绑定功能
2.把这个Car这个组件自动注到容器中
 */
public class MyConfig {


举报

相关推荐

0 条评论