Springboot 组件注册 条件注解

组件注册方式:

@Configuration+@Bean

1、作用

@Bean 是 Spring 中手动注册 Bean 的核心注解,作用在方法上,告诉 Spring: 该方法的返回值会被 Spring 容器管理(成为 IoC 容器中的一个 Bean);

2、自定义bean作用名

Bean 的默认名称是方法名(比如你代码中方法名是 user01),但可以通过 @Bean("userhaha") 自定义 Bean 名称; 容器启动时(或首次获取 Bean 时),会执行该方法并将返回对象存入 IoC 容器,后续获取 Bean 时直接从容器取(单例)或重新执行方法(多例)

复制代码
@Bean("userhaha") // 自定义Bean名称为userhaha,替代默认的user01
public User user01(){...}

3、@Scope 用于指定 Bean 的作用域(生命周期范围),核心作用是控制 Spring 容器创建 Bean 实例的数量和时机。

作用域 说明
singleton (默认)单实例:IoC 容器启动时创建 Bean(懒加载除外),全局仅一个实例
prototype 多实例:每次从容器获取 Bean 时,都会重新执行 @Bean 方法创建新实例
request Web 环境:每个 HTTP 请求创建一个新实例
session Web 环境:每个 HTTP Session 创建一个新实例

举例:

1、创建一个UserConfig配置类(@Configuration),然后在其中定义bean( @Bean("userhaha"))

再指定为多实例 @Scope("prototype")

复制代码
@Configuration
public class UserConfig {
    @Bean("userhaha")
    @Scope("prototype")
    public User user01(){
        var user=new User();
        user.setId(1);
        user.setName("张三");
        return user;
    }
}
​

在启动类中测试bean"userhaha"是单例还是多例。

复制代码
@SpringBootApplication
@MapperScan("org.example.mybatisdemo.mapper")
public class MybatisDemoApplication {
​
    public static void main(String[] args) {
        var ioc=SpringApplication.run(MybatisDemoApplication.class, args);
        /*for(String name:ioc.getBeanDefinitionNames()){
            System.out.println(name);
        }*/
        Object userHaha1=ioc.getBean("userhaha");
        Object userHaha2=ioc.getBean("userhaha");
        System.out.println(userHaha1==userHaha2);
    }
​
}
注解 / 配置 核心作用 实例数量 执行结果(你的代码)
@Bean("userhaha") 注册 Bean 并指定名称 取决于 @Scope -
@Scope("prototype") 多实例作用域 每次 getBean 新实例 userHaha1==userHaha2 → false
默认(无 @Scope) 单实例作用域(singleton) 全局唯一实例 userHaha1==userHaha2 → true

@Component

上篇博客已介绍过。

@Import

1、作用

在 Spring 的开发场景中,我们通常使用 @Component、@Service 或 @Bean 来将类注册到 IoC 容器。但这些方式都有局限性:

@Component 系列:必须能修改目标类的源码(添加注解)。

@Bean 方法:需要在配置类中手写实例化代码,对于大量类或复杂构造函数显得繁琐。

@Import 的出现正是为了解决以下痛点:

  • 第三方类无源码 :如 Druid 连接池中的 FastsqlException,你无法在其源码上加 @Component

  • 批量快速注册 :需要一次性将多个工具类或配置类导入容器,而不想写一堆 @Bean 方法。

  • 解耦配置:将组件的扫描与定义分离,实现模块化配置。

一句话定义@Import 是 Spring 提供的一种**"直通式"注册机制**,它允许开发者直接将指定的 Class 对象"硬塞"进 IoC 容器,无需目标类配合,也无需手动编写工厂方法。

2、工作原理

当 Spring 容器启动并扫描到带有 @Import(XXX.class) 的配置类时,它会直接实例化 XXX 类(调用其默认构造函数),并将其作为 Bean 注册到容器中。

3、组件命名规则

这是 @Import 与普通 @Component 最大的区别之一:

默认名称:目标类的全限定名(Full Qualified Name)。

例如:导入 com.alibaba.druid.FastsqlException,其在容器中的 Bean ID 默认为 "com.alibaba.druid.FastsqlException"。

条件注解

@ConditionalOnXxx

@ConditionalOnClass:如果类路径中存在这个类,则触发指定⾏为

@ConditionalOnMissingClass:如果类路径中不存在这个类,则触发指定⾏为

@ConditionalOnBean:如果容器中存在这个Bean(组件),则触发指定⾏为

@ConditionalOnMissingBean:如果容器中不存在这个Bean(组件),则触发指定⾏为

@ConditionalOnBean(value=组件类型,name=组件名字):判断容器中是否有这个类型的组

件,并且名字是指定的值

场景: ● 如果存在 FastsqlException 这个类,给容器中放⼀个 Cat 组件,名cat01, ● 否则,就给容器中放⼀个 Dog 组件,名dog01 ● 如果系统中有 dog01 这个组件,就给容器中放⼀个 User组件,名zhangsan ● 否则,就放⼀个User,名叫lisi

java 复制代码
@Configuration
public class AppConfig {
​
    @ConditionalOnClass(name="com.alibaba.druid.FastsqlException")
    @Bean
    public Cat cat01(){
        return new Cat();
    }
    @ConditionalOnMissingClass("com.alibaba.druid.FastsqlException")
    @Bean
    public Dog dog01(){
        return new Dog();
    }
​
}
启动类中:

@SpringBootApplication
@MapperScan("org.example.mybatisdemo.mapper")
public class MybatisDemoApplication {
​
    public static void main(String[] args) {
        for (String s : ioc.getBeanNamesForType(Cat.class)) {
            System.out.println("cat:"+s);
        }
        for (String s : ioc.getBeanNamesForType(Dog.class)) {
            System.out.println("dog:"+s);
        }
    }
}

总结

1、本文首先介绍了springboot的组件注册:@Bean;@Component;@ImPort

1)介绍了bean的作用,自定义bean作用名的方式(默认是方法名)还分享了@Scope的作用(用于指定 Bean 的作用域;指明 Spring 容器创建 Bean 实例的数量和时机);介绍四种作用域(singleton(默认),prototype,request,session)及其说明。

2)还介绍了@Import的作用(向 IoC 容器注册组件,解决@Component和@Bean的局限);工作原理;组件命名规则(目标类的全限定名)

2、还列出了一些条件注解:(@ConditionalOnXxx ,@ConditionalOnClass,@ConditionalOnMissingClass,@ConditionalOnBean等等)并举了一个例子来演示@ConditionalOnClass和@ConditionalOnMissingClass注册组件的使用。

3、并介绍了如何在配置文件中为一个java对象赋值(将其注册为bean,再使用@ConfigurationProperties指定前缀);

相关推荐
爆炒西瓜@2 小时前
springboot内存定位,提取数据库账号密码
数据库·spring boot·后端
c++之路2 小时前
Linux进程池与线程池深度解析:设计原理+实战实现(网盘项目架构)
java·linux·架构
阿里云基础软件2 小时前
当 CPU 莫名抖动时,SysOM Agent 如何 3 分钟定位元凶?
java·阿里云·智能运维·操作系统控制台·sysom
野犬寒鸦2 小时前
面试常问:什么是TCP连接:虚拟对话通道的奥秘
服务器·网络·后端·tcp/ip·面试·tcpdump
蜜獾云2 小时前
从linux内核理解Java怎样实现Socket通信
java·linux·运维
new code Boy2 小时前
NestJS、Nuxt.js 和 Next.js
前端·后端
zzz84152 小时前
Spring Boot 3.x 引入springdoc-openapi (内置Swagger UI、webmvc-api)
spring boot·后端·ui
wregjru2 小时前
【读书笔记】Effective C++ 条款5~6:若不想使用编译器自动生成的函数,就该明确拒绝
java·开发语言
华科易迅2 小时前
SQL学习
java·sql·学习