10.配置优先级,bean的管理,SpringBoot原理

发布时间 2023-11-24 17:59:02作者: 回家太晚太悲催

配置优先级,bean的管理,SpringBoot原理

配置优先级:

  • 优先级(低->高):
application.yml
application.yml
application.properties
java系统属性(-Dxxx=xxx)
命令行参数(--xxx=xxx)
  • 例子-设置springboot项目端口号:
java系统属性: -Dserver.port=9000
命令行参数: --server.port=10010

bean的管理:

获取bean:

概念:
  • 默认情况下,Spring项目启动时,会把bean都创建好放在IOC容器中,如果想要主动获取这些bean,可以通过三种方法;
  • 上述所说的[Spring项目启动时,会把其中的bean都创建好] 还会受到作用域及延迟初始化影响,这里主要针对于默认的单例非延迟加载的bean而言;
ioc容器实例化:
  • 获得ioc容器的实例:private ApplicationContext applicationContext;使用@Autowired注解来依赖注入;
  • 再用这个实例调用获取的方法;
获取方法:
  • 根据name获取bean:Object getBean(String name)
  • 根据类型获取bean:<T> T getBean(Class<T> requiredType)
  • 根据name获取bean(带类型转换):<T> T getBean(String name,Class<T> requiredType)##

bean作用域:

概述:
  • 可以通过@Scope 注解来进行配置作用域:
@Scope("prototype")
分类:
作用域 说明
singleton 容器内间 名称 的 bean只有一个实例(单例)(默认)
prototype 每次使用该 bean 时会创建新的实例(非单例)
注意事项:
  • 默认singleton的bean,在容器启动时被创建,可以使用@Lazy注解来延迟初始化(延迟到第一次使用时);
  • prototype的bean,每一次使用该bean的时候都会创建一个新的实例;
  • 实际开发当中,绝大部分的Bean是单例的,也就是说绝大部分Bean不需要配置scope属性;

第三方类:

概念:
  • 如果要管理的bean对象来自于第三方(不是自定义的),就需要用到@Bean注解;
  • 对一个方法使用@Bean注解,springboot会自动调用该方法,将当前方法的返回值对象交给IOC容器管理,成为IOC容器bean;
  • 方法里是用于实例化第三方对象的;
  • 若要管理的第三方bean对象,建议对这些bean进行集中分类配置,可以通过@Configuration注解声明一个配置类;
例子:
@Configuration
public class CommonConfig{
	@Bean
	public SAXReader saxReader(){
		return new SAXReader;
	}
}
注意事项:
  • 通过@Bean注解的name或value属性可以声明bean的名称,如果不指定,默认bean的名称就是方法名;
  • 如果第三方bean需要依赖其他bean对象,直接在bean定义方法中设置形参即可,容器会根据类型自动装配;

SpringBoot原理:

概念:
  • SpringBoot简化Spring框架来开发程序,是依靠起步依赖自动配置来实现的;
起步依赖:
起步依赖的原理就是Maven的依赖传递;
自动配置原理:
概念;
  • SpringBoot的自动配置就是当spring容器启动后,一些配置类、bean对象就自动存入到了IOC容器中,不需要我们手动去生命,从而简化了开发,省去了繁琐的配置操作;
启动类扫描非当前包及子包的类:
  • 方案一:@ComponentScan组件扫描;

    • 写在启动类上;
    • 里面的参数是一个数组,数组里的元素为全类名;
    @ComponentScan("com.example","com.caihongjia")
    @SpringBootApplication
    public class SpringbootwebConfig2Application{
    
    }
    
  • 方案二:@Import导入。使用@Import导入的类会被Spring加载到IOC容器中,导入形式主要有以下几种:

    • 导入 普通类
    • 导入 配置类
    • 导入 ImportSelector 接口实现类;
      • 在导入的第三方依赖中,定义一个类实现ImportSelector接口,重写selectImports()方法;
      • 返回值为数组,数组元素为全类名;
    • 该注解写在启动类上;
    • 里面的参数是一个数组,数组里的元素对应类的class对象;
  • 方案三:@EnableXxx注解,自定义Enable开头的注解,使用@Import注解导入 ImportSelector 接口实现类;

    • 该自定义注解定义在第三方依赖中;
    • 然后再启动类里添加该自定义注解;
@Conditional注解:
  • 作用:按照一定的条件进行判断,在满足给定条件后才会注册对应的bean对象到Spring IOC容器中。

  • 位置:方法、类;

  • @Conditional本身是一个父注解,派生出大量的子注解,以下是较常用的子子注解:

    • @ConditionalOnClass:判断环境中是否有对应字节码文件,才注册bean到IOC容器;
    • @ConditionalOnMissingBean:判断环境中没有对应的bean(类型或名称),才注册bean到IOC容器;
    • @ConditionalOnProperty:判断配置文件(application.yml)中有对应属性和值,才注册bean到IOC容器;
  • 例子:

    @Bean
    @ConditionalOnClass(name="io.jsonwebtoken.Jwts") //当前环境存在指定的这个类时,才注册bean到IOC容器
    public HeaderParser headerParser(){...}
    
    @Bean
    @ConditionalOnMissingBean //当不存在当前类型的bean时,才注册bean到IOC容器
    public HeaderParser headerParser(){...}
    
    @Bean
    @ConditionalOnProperty(name="name",havingValue="caihongjia") //配置文件中存在对应的属性和值,才注册bean到IOC容器
    public HeaderParser headerParser(){...}
    
自定义starter:
起步依赖命名规范:
  • SpringBoot官方:spring-boot-starter-xxx
  • 第三方官方:xxx-spring-boot-starter
操作:
  • 需求:自定义aliyun-oss-spring0starter,完成阿里云OSS操作工具类AliyunOSSUtils的自动配置;

  • 目标:引入起步依赖引入之后,要想使用阿里云OSS,注入AliyunOSSUtils直接使用即可;

  • 步骤:

    • 创建aliyun-oss-spring-boot-starter模块,为依赖管理功能

    • 创建aliyun-oss-spring-boot-autoconfigure模块,为自动配置功能,在starter中引入该模块;

    • 在aliyun-oss-spring-boot-autoconfigure模块中定义自动配置功能

    • 并在resources文件夹下,定义自动配置文件META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

    • 配置文件里面写,自动配置类的全类名;

      aliyun-oss-spring-boot-starter
      
      aliyun-oss-spring-boot-autoconfigure