Springboot细节补充

news/2024/7/8 3:18:58

一、Bean是怎么装配的?

1、bean扫描

在之前的ssm中,spring要么用标签的形式来扫描包,要么使用注解@ComponentScan来扫描

但是在Springboot中,启动类上默认有一个注解@SpringBootApplication,里面就包含了@ComponentScan

注意,springboot默认扫描启动类所在的包及其子包。

也就是说,如果你给启动类也单独放进了一个目录或是把启动类放进了别的包下,那么程序就无法正常运行

但如果你非要给启动类创建一个单独的目录存放,那么就把@ComponentScan单独拿出来。

@ComponentScan(basePackages = "指定包")

但是尽量别这么做

2、bean注册

学习spring的时候就提到过

问:如果我将第三方的jar包(不是自定义的)注入到ioc容器中,那么这些注解还可以使用吗?

答:

        不能,spring提供了两个注解来解决这个问题

        @Bean

        @Import

@Bean

使用@Bean需要在启动类中注册

但是不建议使用这种方式,启动类就让他起到一个启动入口就行了,最好别给他添加太多功能

如果要注册第三方bean,建议在配置类中集中注册

@Confiugration是为了标识是一个配置类,注意要放在启动类的同包或子包下才能使用

问:return回去的这个对象的名称是什么?

答:

        默认方法名是bean对象的名称,在@Bean注解中修改

问:如果方法内部要使用ioc中已经存在的bean对象怎么办?

答:

@Import

我们先写一个配置类,里面用@Bean注册几个bean

在上面说过,配置类注意要放在启动类的同包或子包下才能使用,如果并不想放在同包下,那么就需要使用@Import引入了

在启动类上添加@Import注解其底层是一个数组列表,所以如果有多个配置类的话用{}括起来就行了

不过我们更多还是使用ImportSelector接口实现

写一个接口实现类,然后将一开始写的配置类放进去。不过类太多这样书写也不方便,我们在实际开发中有更清晰的设计,就是将这些配置类统一放在一个配置文件中。resources是管理配置文件的目录,将这些配置类的名称放进去        

public class CommonImportSelector implements ImportSelector {

    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        //读取配置文件的内容
        List<String> imports = new ArrayList<>();
        InputStream is = CommonImportSelector.class.getClassLoader().
                getResourceAsStream("common.imports");
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String line = null;
        try{
            while((line = br.readLine()) != null){
                imports.add(line);
            }
        }catch (IOException e){
            throw new RuntimeException(e);
        }finally {
            if (br != null){
                try {
                    br.close();
                }catch (IOException e){
                    throw new RuntimeException(e);
                }
            }
        }

        return imports.toArray(new String[0]);
    }
}

然后在启动类上@Import的就不是配置类.class了,而是ImportSelector的实现类.class

3、合并注解

上面的例子中,启动类上会有很多个注解,这样看起来很繁琐,不美观。我们想更有逼格一点。

我们之前就说过,启动类的注解@SpringBootApplication就是多个注解组合到一起的,那么我们也可以手动将多个注解组合到一起

Ctrl + 鼠标左键点击@SpringBootApplication注解查看底层

其中最重要的是上最上面的两个注解

        @Target:表示当前注解可以在类上使用

        @Retention:表示当前注解可以在运行时保存

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Import({CommonImportSelector.class})
public @interface EnableCommonConfig {
    
}

最终的启动类如下 


二、注册条件

大部分情况下,我们最好别直接将数据写在java代码中,而是写在配置文件中方便修改。但是这样就又有了问题

数据的使用我们在上一篇博客中已经学过了使用@Value来获取配置文件中的数据。但是当数据不存在的时候就会报错,导致程序停止运行,这是我们在开发中所不希望看到的。因此springboot提供了设置注册生效的注解@Conditional。

不过注解本体使用起来较为麻烦,所以我们最多的还是使用他的几个子类

注解说明
@ConditionalOnProperty配置文件中存在对应属性,才声明该bean
@ConditionalOnMissingBean当不存在当前类型的bean时,才声明该bean
@ConditionalOnClass当前环境存在指定的这个类时,才声明该bean

@ConditionalOnPropetry( prefix = "配置文件中的要使用的数据的前缀" , name = {"数据1","数据n"})

假设现在并没有配置country的信息

那么在我们在进行getbean的时候就会报错,提示这里不存在该对象


三、自动配置原理

遵循约定大约配置的原则,在boot程序启动后,起步依赖中的一些bean对象会自动注入到ioc容器中。

我们之前的步骤并不是完全自动装配,我们除了手动装配bean之外,还需要自己导入到启动类里

先看源码,启动类@SpringBootAutoConfigApplication中组合了@Configuration(说明启动类其实也是一个配置类)、@EnableAutoConfigration

翻源码翻到最后看到一个@ConditionalOnClass,里面一个DispatcherServlet.class。也就是说,若环境中没有DispatcherServlet这个类,那么springboot便不会开启自动装配。而这个类存在于springboot的web起步依赖中,也就是说只有引入springboot的web依赖,我们才可以使用完全自动装配

 springboot自动配置的原理

 


http://lihuaxi.xjx100.cn/news/1786829.html

相关文章

警告:新版Outlook会向微软发送密码、邮件和其他数据

新的免费Outlook会将敏感数据发送给 Microsoft。 在没有通知或询问的情况下&#xff0c;Microsoft 授予自己对新 Outlook 用户的 IMAP 和 SMTP 访问数据的完全访问权限。也就是说&#xff0c;当用户设置 IMAP 帐户时&#xff0c;新的 Outlook 会将访问数据和服务器信息发送给 …

探索STM32系列微控制器的特性和性能

STM32系列微控制器是意法半导体&#xff08;STMicroelectronics&#xff09;公司开发的一款强大的嵌入式微控制器系列。该系列微控制器以其丰富的特性和卓越的性能&#xff0c;成为了嵌入式系统开发领域的首选。本文将深入探索STM32系列微控制器的特性和性能&#xff0c;并结合…

什么是状态机?

什么是状态机&#xff1f; 定义 我们先来给出状态机的基本定义。一句话&#xff1a; 状态机是有限状态自动机的简称&#xff0c;是现实事物运行规则抽象而成的一个数学模型。 先来解释什么是“状态”&#xff08; State &#xff09;。现实事物是有不同状态的&#xff0c;例…

桌面云架构讲解(VDI、IDV、VOI/TCI、RDS)

目录 云桌面架构 VDI 虚拟桌面基础架构 IDV 智能桌面虚拟化 VOI/TCI VOI 虚拟系统架构 TCI 透明计算机架构 RDS 远程桌面服务 不同厂商云桌面架构 桌面传输协议 什么是云桌面 桌面云是虚拟化技术成熟后发展起来的一种应用&#xff0c;桌面云通常也称为云桌面、VDI等 …

Spark3.0中的AOE、DPP和Hint增强

1 Spark3.0 AQE Spark 在 3.0 版本推出了 AQE&#xff08;Adaptive Query Execution&#xff09;&#xff0c;即自适应查询执行。AQE 是 Spark SQL 的一种动态优化机制&#xff0c;在运行时&#xff0c;每当 Shuffle Map 阶段执行完毕&#xff0c;AQE 都会结合这个阶段的统计信…

Linux 安全

Part I: Linux 系统概述 什么是 LinuxLinux 的历史和版本Linux 发行版介绍Linux 的优缺点 Part II: Linux 安装与配置 5. 硬件要求与准备工作 6. 安装 Linux 操作系统 7. Linux 系统初始化设置 8. Linux 系统更新与升级 9. Linux 基础配置 Part III: Linux 命令行 10. Linux…

解决Map序列化成JSON字符串传给前端后属性乱序问题

map序列化成json对象传递给前端时&#xff0c;map中属性的顺序会按首字母重新排序 json对象中的属性没有顺序而言&#xff0c;一次序列化、反序列化就会乱。 试过把map转成了JSON字符串&#xff0c;传给前端&#xff0c;还是不行 JSON.parseObject(JSON.toJSONString(contra…

springboot(ssm 拍卖行系统 在线拍卖平台 Java(codeLW)

springboot(ssm 拍卖行系统 在线拍卖平台 Java(code&LW) 开发语言&#xff1a;Java 框架&#xff1a;ssm/springboot vue JDK版本&#xff1a;JDK1.8&#xff08;或11&#xff09; 服务器&#xff1a;tomcat 数据库&#xff1a;mysql 5.7&#xff08;或8.0&#xff09…