SpringBoot @Import与@Conditional注解使用详解
作者:一根头发学一年 发布时间:2023-12-14 16:42:45
说明:基于atguigu学习笔记。
在了解spring boot自动配置原理前,再来了解下两个注解@Import注解和@Conditional注解。
@Import
@Import注解主要用于导入某些特殊的Bean,这些特殊的Bean和Bean Definitaion 有关。
主要用于导入@Configuration 类,ImportSelector和ImportBeanDefinitionRegistrar接口的实现类。
@Import可以添加在@SpringBootApplication(启动类)、@Configuration(配置类)、@Component(组件类)对应的类上。
一般在Spring boot 中配置都一般都是自动导入的,所以我们不需要使用@Import,但是如果你你想导入的配置类不在自动扫包路径,那么该配置类就需要使用@Import导入,尤其是第三方jar包的配置类都需要借助@Import来导入。
这里我们首先熟悉基本语法,具体的用法后面再学。
示例:
还使用上一章里项目示例:@Configuration注解和@Bean注解
使用 @Import导入我们需要的类,这里导入我们自己创建的类和第三方logback jar包里的类,如下:
config类:
package com.example.ethan.config;
import ch.qos.logback.core.db.DBHelper;
import com.example.ethan.bean.Dept;
import com.example.ethan.bean.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Import({User.class, DBHelper.class})
@Configuration(proxyBeanMethods=true)
public class ConfigDemo {
@Bean
public User user01(){
User zhangsan = new User("zhangsan", 18);
//user组件依赖了Dept组件
zhangsan.setDept(rd());
return zhangsan;
}
@Bean("my rd")
public Dept rd(){
return new Dept("研发部");
}
}
主程序
package com.example.ethan;
import ch.qos.logback.core.db.DBHelper;
import com.example.ethan.bean.Dept;
import com.example.ethan.bean.User;
import com.example.ethan.config.ConfigDemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class EthanApplication {
public static void main(String[] args) {
// 返回ioc容器
ConfigurableApplicationContext run = SpringApplication.run(EthanApplication.class, args);
// 只查看User类型的Bean
String[] beanDefinitionNames = run.getBeanNamesForType(User.class);
System.out.println("========================");
for (String name : beanDefinitionNames) {
System.out.println(name);
}
DBHelper bean = run.getBean(DBHelper.class);
System.out.println(bean);
// com.example.ethan.bean.User
//user01
//ch.qos.logback.core.db.DBHelper@67207d8a
}
}
可以看到,使用 @Import注解,会给容器中自动创建出这两个类型的Bean,且Bean的名字是全类名。
@Conditional
满足Conditional指定的条件,则进行注入指定Bean。
@Conditional是一个根注解,下面还派生了许多其他注解
@Conditional注解可以加在方法上也可以加在类上。当加在类上,当条件不成立,类中所有代码都不执行,如果加在方法上,则只这个方法不执行。
下面以@ConditionalOnBean(条件是判断是否含有某个Bean)为例,演示代码如下:
首先放在方法上:
package com.example.ethan.config;
import com.example.ethan.bean.Dept;
import com.example.ethan.bean.User;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods=true)
public class ConfigDemo {
@Bean("my rd")
public Dept rd(){
return new Dept("研发部");
}
@Bean
@ConditionalOnBean(name = "my rd")
public User user01(){
User zhangsan = new User("zhangsan", 18);
//user组件依赖了Dept组件
zhangsan.setDept(rd());
return zhangsan;
}
}
主程序:
package com.example.ethan;
import ch.qos.logback.core.db.DBHelper;
import com.example.ethan.bean.Dept;
import com.example.ethan.bean.User;
import com.example.ethan.config.ConfigDemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class EthanApplication {
public static void main(String[] args) {
// 返回ioc容器
ConfigurableApplicationContext run = SpringApplication.run(EthanApplication.class, args);
boolean my_rd = run.containsBean("my rd");
System.out.println("容器中含有my rd这个Bean:" + my_rd);
boolean user01 = run.containsBean("user01");
System.out.println("容器中含有user01这个Bean:" + user01);
}
}
这时候两个好结果都是true,因为按照顺序注入Bean时,先注入了"my rd"这个Bean到容器,然后在注入user01时,检查容器中含有my rd"这个Bean,就把user01也注入了。
如果把条件里name改为不存在的如"my rd02",那么入user01就不会注入容器。
下面把注解放到类上:
package com.example.ethan.config;
import com.example.ethan.bean.Dept;
import com.example.ethan.bean.User;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods=true)
@ConditionalOnBean(name = "my rd")
public class ConfigDemo {
@Bean("my rd")
public Dept rd(){
return new Dept("研发部");
}
@Bean
public User user01(){
User zhangsan = new User("zhangsan", 18);
//user组件依赖了Dept组件
zhangsan.setDept(rd());
return zhangsan;
}
}
这时候两个Bean都不会注入容器,因为在执行这个类时检查条件不成立。
这里对@ConditionalOnBean有个初步了解,具体何种用法类似,可举一反三。
参考:
SpringBoot之@Import注解使用
来源:https://blog.csdn.net/qq_43745578/article/details/127251080


猜你喜欢
- 一、微信官方文档微信支付开发流程(公众号支付)首先我们到微信支付的官方文档的开发步骤部分查看一下需要的设置。[图片上传失败...(image
- 经过几天的折腾,终于到了学习一个重量级的查询方式上,使用@Query注解,使用注解有两种方式,一种是JPQL的SQL语言方式,一种是原生SQ
- 函数式接口1.1 函数式接口概述函数式接口:有且仅有一个抽象方法的接口Java中的函数式编程体现就是Lambda表达式,所以函数式接口就是可
- 看完本文你将了解:ACTION_CANCEL的触发时机滑出子View区域会发生什么?为什么不响应onClick()事件首先看一下官方的解释:
- 前言1.Map里面只能存放对象,不能存放基本类型,例如int,需要使用Integer2.Map集合取出时,如果变量声明了类型,会先进行拆箱,
- 一、概述热修复这项技术,基本上已经成为项目比较重要的模块了。主要因为项目在上线之后,都难免会有各种问题,而依靠发版去修复问题,成本太高了。现
- 前言对于 InterruptedException,一种常见的处理方式是 “生吞(swallow)” 它 —— 捕捉它,然后什么也不做(或者
- 规则1(无继承情况下):对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序依次是(静态变量、静态初始化块)>(变量、
- •readonly和const都是用来标识常量的[1]。•const可用于修饰class的field或者一个局部变量(local varia
- 引入第三方jar包或者查看Java源码的时候,经常遇到问题如下:decompiled.class file bytecode version
- 在分支较多的时候,switch的效率比if高,在反汇编中我们即可看到效率高的原因一、switch语句1、在正向编码时,switch语句可以看
- springboot项目没有mainClass实现打包运行项目分为两个部分,一个是业务代码模块,一个是框架模块,运行class放在框架部分,
- 一、文件上传的原理分析1、文件上传的必要前提a、表单的method必须是postb、表单的enctype属性必须是multipart/for
- 1 常量定义在程序中存在大量的数据来代表程序的状态,其中有些数据在程序运行过程中值不能发生改变,这些数据在程序中被叫做常量。2 常量语法命名
- 大家好,这是 C# 9.0 新特性短系列的第 5 篇文章。弃元(Discards) 是在 C# 7.0 的时候开始支持的,它是一种人为丢弃不
- 一、程序的三种结构顺序结构分支结构循环结构二、条件语句if 语句是最有用的控制结构之一。 if … else …语句的语法:if (布尔表达
- 有时候你希望在一个嵌套循环的外层循环中执行Continue操作。例如,假设你有一连串的标准,和一堆items。并且你希望找到一个符合每个标准
- 今天被数据大神说了,对接第三方接口返回的json字段我想用驼峰形式,他说我这样不专业。所以就改了,认怂。记住以后再次对接rest接口,返回的
- 俗话说,工欲善其事,必先利其器。要做微信公众号开发,两样东西不可少,那就是要有一个用来测试的公众号,还有一个用来调式代码的开发环境。测试公众
- 锁是个非常有用的工具,运用场景非常多,因为它使用起来非常简单,而且易于理解。但同时它也会带来一些困扰,那就是可能会引起死锁,一旦产生死锁,就