SpringBoot2-[SpringBoot自动装配、容器功能]

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
简介: SpringBoot2-[SpringBoot自动装配、容器功能]

在这里插入图片描述

👨🏻‍🎓博主介绍:大家好,我是芝士味的椒盐,一名在校大学生,热爱分享知识,很高兴在这里认识大家🌟
🌈擅长领域:Java、大数据、运维、电子
🙏🏻如果本文章各位小伙伴们有帮助的话,🍭关注+👍🏻点赞+🗣评论+📦收藏,相应的有空了我也会回访,互助!!!
🤝另本人水平有限,旨在创作简单易懂的文章,在文章描述时如有错,恳请各位大佬指正,在此感谢!!!

@[TOC]

SpringBoot自动装配

  • 主类使用了@SpringBootApplication,其内部的@EnableAutoConfiguration就会作用,开启自动装配

    # Initializers
    org.springframework.context.ApplicationContextInitializer=\
    org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
    org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener
    
    # Application Listeners
    org.springframework.context.ApplicationListener=\
    org.springframework.boot.autoconfigure.BackgroundPreinitializer
    
    # Auto Configuration Import Listeners
    org.springframework.boot.autoconfigure.AutoConfigurationImportListener=\
    org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener
    
    # Auto Configuration Import Filters
    org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\
    org.springframework.boot.autoconfigure.condition.OnBeanCondition,\
    org.springframework.boot.autoconfigure.condition.OnClassCondition,\
    org.springframework.boot.autoconfigure.condition.OnWebApplicationCondition
                                                                                                ......
  • 按需加载,只有导入了相关的依赖之后才会生效
  • 包扫描

    • 默认是扫描引导类(主类)的包所在的包及其子包下的Bean。
    • 各种配置拥有默认值

      • 默认配置最终都是映射到某个类上,如:MultipartProperties
      • 配置文件的值最终会绑定每个类上,这个类会在容器中创建对象
    • 也可以更改包扫描位置使用如下

      @SpringBootApplication(scanBasePackages = "icu.lookyousmileface.springboot_gettingstarted.controller")
    • 还可以不使用@SpringApplication注解,使用@ComponentScan注解,不可以和@SpringApplication注解一起用

      @SpringBootConfiguration
      @EnableAutoConfiguration
      @ComponentScan("icu.lookyousmileface.springboot_gettingstarted")
      • 会冲突

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

SpringBoot容器功能

  • @Configuration

    • Full模式与Lite模式

      • 配置 类组件之间无依赖关系用Lite模式加速容器启动过程,减少判断
      • 配置类组件之间有依赖关系,方法会被调用得到之前单实例组件,用Full模式
      @Configuration(proxyBeanMethods = true)
      public class MyConfig {
      
          @Bean
          public Human human(){
              return new Human("松江",18,'男');
          }
      
          public Pet pet(){
              return new Pet("小黑","白色");
          }
      }
      
      public static void main(String[] args) {
              ConfigurableApplicationContext run = SpringApplication.run(SpringbootGettingstartedApplication.class);
              //查看场景启动器带来的组件
              String[] beanDefinitionNames = run.getBeanDefinitionNames();
              Arrays.stream(beanDefinitionNames).forEach(S->System.out.println(S));
              //从容器获得对象
              Human human1 = run.getBean("human",Human.class);
              Human human2 = run.getBean("human",Human.class);
              System.out.println(human1==human2);
              //icu.lookyousmileface.springboot_gettingstarted.config.MyConfig$$EnhancerBySpringCGLIB$$21ae3889@15515c51 表示被代理
              MyConfig myConfig = run.getBean(MyConfig.class);
              System.out.println(myConfig);
              //config的proxyBeanMethods = true为单实列,否则每次调用都会产生一个新的对象
              Human human = myConfig.human();
              Human human3 = myConfig.human();
              System.out.println(human3==human);
      }
      • config类配置代替了大量的xml配置
  • @Bean(表示对象组件)、@Component(表示组件)、@Controller(表示控制器组件)、@Service(表示业务层组件)、@Repository(标注表示数据库组件)
  • @ComponentScan(包扫描)、@Import(导入组件)

    • @Import:使用@Import导入组件,其名字为全类名如:Human,@Bean注册的注册的类为首字母小写形势human

      */
      //使用@Import导入组件,其名字为全类名如:Human,@Bean注册的注册的类为首字母小写形势human
      @Import({Human.class,Pet.class})
      @Configuration(proxyBeanMethods = true)
      public class MyConfig {
      
          @Bean
          public Human human(){
              return new Human("松江",18,'男');
          }
      
          public Pet pet(){
              return new Pet("小黑","白色");
          }
      }
  • @Conditional

    • 条件装配:满足Conditional指定的条件,则进行组件注入,其下由多个子类如下:

      在这里插入图片描述

    • 代码实验:

      @Configuration
      public class MyConfig {
      
          @ConditionalOnMissingBean(name = "peto1")
          @Bean
          public Human human01(){
              return new Human("宋江",46,'男');
          }
      
      //    @Bean
          public Pet Peto1(){
              return new Pet("小黄","yellow");
          }
      }
      • @ConditionalOnMissingBean(name = "peto1")也就是说,如果没有"pet01"Bean这个名称的容器就创建human01,否则就将不创建Human类的对象, 可以作用在方法和类上。
  • @ImportResource(引入原生的配置文件), 例如:要倒入Spring原生bean配置文件如下

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    
        <bean id="hu01" class="icu.lookyousmileface.springboot_gettinggide.bean.Human">
            <property name="name" value="武松"></property>
            <property name="age" value="19"></property>
            <property name="sex" value="男"></property>
        </bean>
    
        <bean id="pe01" class="icu.lookyousmileface.springboot_gettinggide.bean.Pet">
            <property name="name" value="cat"></property>
            <property name="color" value="red"></property>
        </bean>
    </beans>
    • 就可以在配置类上加上该注解如下,bean此时在resources目录下:

      @Configuration
      @ImportResource("classpath:bean.xml")
      public class MyConfig {
      
      //    @ConditionalOnMissingBean(name = "peto1")
          @Bean
          public Human human01(){
              return new Human("宋江",46,'男');
          }
      
          @Bean
          public Pet Peto1(){
              return new Pet("小黄","yellow");
          }
      }
  • 配置绑定(@ConfigurationProperties+@Component标注在要绑定属性的类上)

    • application.yml(选用的是yml,选用properties遇到中文会出现乱码)

      myhuman:
        name: 宋江
        age: 89
        sex: 男
    • Human.java

      @Component
      prefix表示和配置文件的前缀相同的属性开始匹配,也就是上述application.yml中的myhuman
      @ConfigurationProperties(prefix = "myhuman")
      public class Human {
          private String name;
          private int age;
          private String sex;
      }
      • ⚠️注意配置绑定之前需要导入配置出绑定处理器,解决没有提示的问题

        <!--配置文件处理器,properties参数绑定对象-->
          <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-configuration-processor</artifactId>
          <optional>true</optional>
        </dependency>
      • ⚠️为了减少不必要插件编译进jar包或war包,可进行排除

        <build>
                <plugins>
                    <plugin>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-maven-plugin</artifactId>
                        <!--编译时排除不必要的类-->
                        <configuration>
                            <excludes>
                                <exclude>
                                    <groupId>org.projectlombok</groupId>
                                    <artifactId>lombok</artifactId>
                                </exclude>
                                <exclude>
                                    <groupId>org.springframework.boot</groupId>
                                    <artifactId>spring-boot-configuration-processor</artifactId>
                                </exclude>
                            </excludes>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
    • application.yml
    • Human.java

      @AllArgsConstructor
      @NoArgsConstructor
      @Data
      @Accessors(chain = true)
      @EqualsAndHashCode
      //@Component
      @ConfigurationProperties(prefix = "myhuman")
      public class Human {
          private String name;
          private int age;
          private String sex;
      }
    • MyConfig.java

      @Configuration
      //@ImportResource("classpath:bean.xml")
      @EnableConfigurationProperties(Human.class)
      public class MyConfig {
      
      //    @ConditionalOnMissingBean(name = "peto1")
      //    @Bean
      //    public Human human01(){
      //        return new Human("宋江",46,"男");
      //    }
      
          @Bean
          public Pet Peto1(){
              return new Pet("小黄","yellow");
          }
      }
      • @EnableConfigurationProperties(Human.class):表示支持某个类参数绑定,也就是开启配置绑定功能,将Human这个组件注册到容器。注意不要存在其他注册该容器的情况否则报错。
  • 自动配置原理

    • @SpringBootConfiguration:@Configuration是一个配置类
    • @ComponentScan:包扫描
    • @EnableAutoConfiguration:自动装配核心

      @AutoConfigurationPackage
      @Import({AutoConfigurationImportSelector.class})
      1. @AutoConfigurationPackage

        @Import(AutoConfigurationPackages.Registrar.class)  //给容器中导入一个组件
        public @interface AutoConfigurationPackage {}
        
        //利用Registrar给容器中导入一系列组件
        //将指定的一个包下的所有组件导入进来?MainApplication 所在包下。
      2. @Import(AutoConfigurationImportSelector.class)

        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

        在这里插入图片描述
        在这里插入图片描述

    • 按需开启自动配置项

      虽然127个场景的所有自动配置启动的时候默认全部加载。xxxxAutoConfiguration
      按照条件装配规则(@Conditional),最终会按需配置。
    • 修改自动配置

                      @Bean
              @ConditionalOnBean(MultipartResolver.class)  //容器中有这个类型组件
              @ConditionalOnMissingBean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME) //容器中没有这个名字 multipartResolver 的组件
              public MultipartResolver multipartResolver(MultipartResolver resolver) {
                  //给@Bean标注的方法传入了对象参数,这个参数的值就会从容器中找。
                  //SpringMVC multipartResolver。防止有些用户配置的文件上传解析器不符合规范
                  // Detect if the user has created a MultipartResolver but named it incorrectly
                  return resolver;
              }
      给容器中加入了文件上传解析器;
      • SpringBoot默认会在底层配好所有的组件。但是如果用户自己配置了以用户的优先

                @Bean
            @ConditionalOnMissingBean
            public CharacterEncodingFilter characterEncodingFilter() {
            }
    • 总结:

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

      • 引入场景依赖
          • https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-starter
      • 查看自动配置了哪些(选做)
          • 自己分析,引入场景对应的自动配置一般都生效了
          • 配置文件中debug=true开启自动配置报告。Negative(不生效)\Positive(生效)
      • 是否需要修改
          • 参照文档修改配置项
              • https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html#common-application-properties
              • 自己分析。xxxxProperties绑定了配置文件的哪些。
          • 自定义加入或者替换组件
              • @Bean、@Component。。。
          • 自定义器  XXXXXCustomizer;
          • ......
  • 开发小技巧

    • lombok:通过注解的方式创建get/set/toString等方法,提高编写bean的效率,也可以使用Slfj日志输出。
    • devtools:跟JRebel差不多的热部署工具,只要倒入其依赖即可使用,快捷键Control+F9

      <!--springboot的热部署工具-->
      <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-devtools</artifactId>
                  <version>2.0.4.RELEASE</version>
      </dependency>
相关文章
|
7天前
|
消息中间件 缓存 Java
手写模拟Spring Boot启动过程功能
【11月更文挑战第19天】Spring Boot自推出以来,因其简化了Spring应用的初始搭建和开发过程,迅速成为Java企业级应用开发的首选框架之一。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,帮助读者深入理解其工作机制。
22 3
|
7天前
|
Java 开发者 微服务
手写模拟Spring Boot自动配置功能
【11月更文挑战第19天】随着微服务架构的兴起,Spring Boot作为一种快速开发框架,因其简化了Spring应用的初始搭建和开发过程,受到了广大开发者的青睐。自动配置作为Spring Boot的核心特性之一,大大减少了手动配置的工作量,提高了开发效率。
24 0
|
20天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,创建并配置 Spring Boot 项目,实现后端 API;然后,使用 Ant Design Pro Vue 创建前端项目,配置动态路由和菜单。通过具体案例,展示了如何快速搭建高效、易维护的项目框架。
95 62
|
6天前
|
Ubuntu 网络安全 容器
KubeSphere 是一个开源的容器平台,提供丰富的功能和便捷的操作界面,适用于企业容器化部署和管理
KubeSphere 是一个开源的容器平台,提供丰富的功能和便捷的操作界面,适用于企业容器化部署和管理。本文详细介绍了如何在 Ubuntu 22.04 上安装 KubeSphere,包括系统要求、安装依赖项、设置防火墙、下载安装脚本、选择安装选项、验证安装结果等步骤,并提供了常见问题的解决方法。希望本文能为读者提供实用的参考和帮助。
18 3
|
17天前
|
前端开发 Java easyexcel
SpringBoot操作Excel实现单文件上传、多文件上传、下载、读取内容等功能
SpringBoot操作Excel实现单文件上传、多文件上传、下载、读取内容等功能
57 8
|
18天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,帮助开发者提高开发效率和应用的可维护性。
36 2
|
22天前
|
JSON Java API
springboot集成ElasticSearch使用completion实现补全功能
springboot集成ElasticSearch使用completion实现补全功能
24 1
|
26天前
|
存储 Java 数据管理
强大!用 @Audited 注解增强 Spring Boot 应用,打造健壮的数据审计功能
本文深入介绍了如何在Spring Boot应用中使用`@Audited`注解和`spring-data-envers`实现数据审计功能,涵盖从添加依赖、配置实体类到查询审计数据的具体步骤,助力开发人员构建更加透明、合规的应用系统。
|
1月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,包括版本兼容性、安全性、性能调优等方面。
148 1
|
21天前
|
JavaScript Java 项目管理
Java毕设学习 基于SpringBoot + Vue 的医院管理系统 持续给大家寻找Java毕设学习项目(附源码)
基于SpringBoot + Vue的医院管理系统,涵盖医院、患者、挂号、药物、检查、病床、排班管理和数据分析等功能。开发工具为IDEA和HBuilder X,环境需配置jdk8、Node.js14、MySQL8。文末提供源码下载链接。