1.配置优先级

  • SpringBoot中支持三种格式的配置文件
    • application.properties
    • application.yml
    • application.yaml

【注意点:虽然springboot支持多种格式配置文件,但是在项目开发是,推荐统一使用一种格式的配置(yml是直流)】

优先级:application.properties->application.yml->application.yaml

  • SpringBoot 除了支持配置文件属性配置,还支持Java系统属性命令行参数的方式进行属性配置
    • Java系统属性
      • -Dserver.port=9000
    • 命令行参数
      • --server.port=10010

image-20230810235045343.png

命令行参数 -> Java系统属性

  • 打包jar,用cmd来运行jar
    • 执行maven打包指令 package
    • 执行java指令,运行jar包
java -Dserver.port=9000 -jar .....jar --server.port=10010

【注意:springboot项目进行打包时,需要引入插件 spring-boot-maven-plugin(基于官网骨架创建项目,会自动添加该插件)】

2.Bean管理

2.1、获取bean

  • 默认情况下,Spring项目启动时,会吧bean都创建好放在IOC容器中,如果想要主动获取这些bean,可以通过:

    • 根据name获取beam
    Object getBean(String name);
    
    • 根据类型获取bean
    <T> T getBean(Class<T> requiredType);
    
    • 根据name和类型获取bean
    <T> T getBean(String name,Class<T> requiredType);
    
@Autowired
private ApplicationContext context; //IOC容器
@Autowired
private SAXReader saxReader;
//获取bean对象
@Test
public void testGetBean(){
    //根据bean的名称获取
    DeptController deptController = (DeptController) context.getBean("deptController");
    System.out.println(deptController);
    //根据bean的类型获取
    DeptController deptController2 = context.getBean(DeptController.class);
    System.out.println(deptController2);
    //根据bean的名称 及 类型获取
    DeptController deptController3 = context.getBean(DeptController.class,"deptController");
    System.out.println(deptController3);
}

【注意点:spring项目启动时,会吧其中的bean都创建好,但其还会受到作用域及延迟初始化影响】

2.2、bean作用域

  • Spring支持五种作用域,后三种在web环境才生效

image-20230810235057898.png

  • 可以通过 @Scope 注解来进行配置作用域
//@Lazy  //延迟初始化:使用的时候才会实例化
@Scope("prototype")   //设置bean的作用域
@RestController
@RequestMapping("/depts")
public class DeptController {
    ....
}
  • 【注意点】
    • 默认singleton的bean,在容器启动时被创建,可以使用@Lazy注解来延迟初始化(延迟到第一次使用时)
    • prototype的bean,每一次使用该bean的时候都会创建一个新的实例
    • 实际开发中,大部分bean都是单例的,绝大部分bean是不需要配置scope属性的

2.3、第三方bean

  • @Bean
    • 如果要管理的bean对象来自于第三方(不是自定义的),是无法用@Component及衍生注解声明bean的,就需要用到@Bean注解
@Configuration
public class CommonConfig {
    //声明第三方bean
    @Bean //将当前方法的返回值对象交给IOC容器管理,称为IOC容器bean
    public SAXReader saxReader(DeptService deptService){//自动注入deptService
        System.out.println(deptService);
        return new SAXReader();
    }
}
  • 【注意点】
    • 通过@Bean让注解的name/value属性指定bean名称,如果未指定,默认是方法名
    • 如果第三方bean需要依赖其它bean对象,直接在bean定义方法中设置形参即可,容易会根据类型自动的依赖注入

3.SpringBoot原理

3.1、起步依赖

image-20230810235105510.png

image-20230810235117040.png

3.2、自动配置

  • SpringBoot的自动配置就是当spring容器启动后,一些配置类、bean对象就自动存入到了IOC容器中,不需要我们手动去声明,从而简化了开发,省去了繁琐的配置操作

当使用到其它模块的类时,可以将该模块的依赖放入需要项目的pom.xml文件当中

image-20230810235125749.png

之后在项目的启动类中使用@ComponentScan来扫描引入依赖的包

@SpringBootApplication
@ComponentScan({"com.itheima","com.example"})
public class SpringbootWebConfig2Application {
    public static void main(String[] args) {   SpringApplication.run(SpringbootWebConfig2Application.class, args);
    }
}
  • 自动配置原理

    • 方法一:@ComponentScan组件扫描

image-20230810235133118.png

  • 方法二:@Import导入,使用@Import导入的类会被spring加载到IOC容器中,导入形式:

    • 导入普通类

    • 导入配置类

    • 导入ImportSelector接口实现类
    @SpringBootApplication
    //@ComponentScan({"com.itheima","com.example"})
    //@Import({TokenParser.class})  //导入普通类 交给IOC容器
    //@Import({HeaderConfig.class})  //导入配置类,交给IOC容器
    //@Import({MyImportSelector.class})  //导入ImportSelector接口实现类
    public class SpringbootWebConfig2Application {
    
      public static void main(String[] args) {
          SpringApplication.run(SpringbootWebConfig2Application.class, args);
      }
    }
    
  • 源码跟踪

image-20230810235139154.png

  • @SpringBootApplication:该注解标识在SpringBoot工程引导类上,是SpringBoot中非常重要的注解,由三个部分组成

    • @SpringBootConfiguration:该注解于@Configuration注解作用相同,用来声明当前也是一个配置类
    • @ComponentScan:组件扫描,默认扫描当前引导类所在包及其子包
    • @EnableConfiguration:SpringBoot实现自动化配置的核心注解
  • @Conditional

    • @ConditionalOnClass
    @Bean
    @ConditionalOnClass(name = "io.jsonwebtoken.Jwts")//坏境中存在指定的找个类,才会吧该bean加入IOC容器
    public HeaderParser headerParser(){
        return new HeaderParser();
    }
    
    • @ConditionalOnMissignBean
    @ConditionalOnMissingBean  //不存在该类型的bean 才会将该bean加入到IOC容器当中  ---指定类型(value属性) 或名称(name属性)
    
    • @ConditionalOnProperty
    @ConditionalOnProperty(name="name",havingValue = "haonan")  //配置文件中存在指定的属性与值,才会将bean添加到IOC容器当中
    

3.3、案例(自定义start)

  • 场景
    • 在实际开发中,经常会定义一些公共组件,提供给各个项目团队使用。而在SpringBoot的项目中,一般会将这些公共组件封装为SpringBoot的starter

image-20230810235146441.png

  • 需求
    • 自定义aliyun-oss-spring-boot-starter,完成阿里云OSS操作工具类 AliyunOSSUtils 的自动配置
  • 目的

    • 引入起步依赖之后,想使用阿里云OSS,直接注入AliyunOSSUtils直接使用即可
  • 创建模块aliyun-oss-spring-boot-autoconfigure和aliyun-oss-spring-boot-starter

    在autoconfigure模块中,导入需要用到的阿里云依赖,放入工具类和OSS配置类

    @Component
    public class AliOSSUtils {
        @Autowired
        private AliOSSProperties aliOSSProperties;
        /**
         * 实现上传图片到OSS
         */
        public String upload(MultipartFile file) throws IOException {
            //获取AliOSSProperties中的属性值
            String endpoint = aliOSSProperties.getEndpoint();
            String accessKeyId = aliOSSProperties.getAccessKeyId();
            String accessKeySecret = aliOSSProperties.getAccessKeySecret();
            String bucketName = aliOSSProperties.getBucketName();
    
            // 获取上传的文件的输入流
            InputStream inputStream = file.getInputStream();
    
            // 避免文件覆盖
            String originalFilename = file.getOriginalFilename();
            String fileName = UUID.randomUUID().toString() + originalFilename.substring(originalFilename.lastIndexOf("."));
    
            //上传文件到 OSS
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
            ossClient.putObject(bucketName, fileName, inputStream);
    
            //文件访问路径
            String url = endpoint.split("//")[0] + "//" + bucketName + "." + endpoint.split("//")[1] + "/" + fileName;
            // 关闭ossClient
            ossClient.shutdown();
            return url;// 把上传到oss的路径返回
        }
    
    }
    
    @Data
    @Component
    @ConfigurationProperties(prefix = "aliyun.oss")
    public class AliOSSProperties {
        private String endpoint;
        private String accessKeyId;
        private String accessKeySecret;
        private String bucketName;
    }
    

去掉不需要的注解,因为不会进行扫描包,而是引入依赖的形式,两个类上面的@Component注解来标识注入bean已经没用,所以丢掉

  • 修改两个类

【Utils】

public class AliOSSUtils {

    private AliOSSProperties aliOSSProperties;

    public AliOSSProperties getAliOSSProperties() {
        return aliOSSProperties;
    }

    public void setAliOSSProperties(AliOSSProperties aliOSSProperties) {
        this.aliOSSProperties = aliOSSProperties;
    }

    /**
     * 实现上传图片到OSS
     */
    public String upload(MultipartFile file) throws IOException {
        //获取AliOSSProperties中的属性值
        String endpoint = aliOSSProperties.getEndpoint();
        String accessKeyId = aliOSSProperties.getAccessKeyId();
        String accessKeySecret = aliOSSProperties.getAccessKeySecret();
        String bucketName = aliOSSProperties.getBucketName();

        // 获取上传的文件的输入流
        InputStream inputStream = file.getInputStream();

        // 避免文件覆盖
        String originalFilename = file.getOriginalFilename();
        String fileName = UUID.randomUUID().toString() + originalFilename.substring(originalFilename.lastIndexOf("."));

        //上传文件到 OSS
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        ossClient.putObject(bucketName, fileName, inputStream);

        //文件访问路径
        String url = endpoint.split("//")[0] + "//" + bucketName + "." + endpoint.split("//")[1] + "/" + fileName;
        // 关闭ossClient
        ossClient.shutdown();
        return url;// 把上传到oss的路径返回
    }

}

【properties】

@Data
@ConfigurationProperties(prefix = "aliyun.oss")
public class AliOSSProperties {
    private String endpoint;
    private String accessKeyId;
    private String accessKeySecret;
    private String bucketName;
}
  • 创建自动配置类AliOSSAutoConfiguration
@Configuration
@EnableConfigurationProperties(AliOSSProperties.class)
public class AliOSSAutoConfiguration {

    @Bean
    public AliOSSUtils aliOSSUtils(AliOSSProperties aliOSSProperties){
        AliOSSUtils aliOSSUtils = new AliOSSUtils();
        aliOSSUtils.setAliOSSProperties(aliOSSProperties);
        return aliOSSUtils;
    }
}
  • 运行测试,再使用的模块中,导入starter依赖,注入AliOSSUtils的Bean即可
@RestController
public class UploadController {
    @Resource
    private AliOSSUtils aliOSSUtils;
    @PostMapping("/upload")
    public String upload(MultipartFile image) throws Exception {
        //上传文件到阿里云 OSS
        String url = aliOSSUtils.upload(image);
        return url;
    }

}

results matching ""

    No results matching ""