Springboot笔记<3> 组件注入注解@Conditional与@import
@Conditional
@Conditional是Spring4新提供的注解,它的作用是按照一定的条件进行判断,满足条件给容器注册bean。
创建ConfigConditional类和测试类ConfigConditionalTest
@Configuration
public class ConfigConditional {
@Bean(name = "xiaoming")
public Student getStudent1(){
Student student = new Student();
student.setName("xiaoming");
student.setAge(18);
return student;
}
@Bean(name = "xiaohong")
public Student getStudent2(){
Student student = new Student();
student.setName("xiaohong");
student.setAge(17);
return student;
}
}
测试类ConfigConditionalTest
输出结果为{xiaoming=Student(age=18, name=xiaoming), xiaohong=Student(age=17, name=xiaohong)},说明两个Student实例被注入进容器。
public class ConfigConditionalTest {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ConfigConditional.class);
@Test
public void test1() {
Map<String, Student> map = applicationContext.getBeansOfType(Student.class);
System.out.println(map);
}
}
//输出为{xiaoming=Student(age=18, name=xiaoming), xiaohong=Student(age=17, name=xiaohong)}
如果我想根据当前操作系统来注入Student实例,只有在非windows操作系统的情况下注入xiaoming。
这就需要我们用到@Conditional注解了。
@Conditional作用
Class<? extends Condition>[] value()说明@Conditional注解传入的是一个Class数组,存在多种条件类的情况。@Target({ElementType.TYPE, ElementType.METHOD})说明@Conditional可以作用在方法和类上,一个方法只能注入一个bean实例,所以@Conditional标注在方法上只能控制一个bean实例是否注入。标注在类上:一个类中可以注入很多实例,@Conditional标注在类上就决定了一批bean是否注入。
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
/**
* All {@link Condition} classes that must {@linkplain Condition#matches match}
* in order for the component to be registered.
*/
Class<? extends Condition>[] value();
}
@Conditional举例
创建WindowsConfig,非windows系统,返回true。
public class WindowsConfig implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
//获取ioc使用的beanFactory
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
//获取类加载器
ClassLoader classLoader = context.getClassLoader();
//获取当前环境信息
Environment environment = context.getEnvironment();
//获取bean定义的注册类
BeanDefinitionRegistry registry = context.getRegistry();
//获得当前系统名
String property = environment.getProperty("os.name");
//不包含Windows则说明不是windows系统,返回true
if (!property.contains("Windows")) {
return true;
}
return false;
}
}
@Conditional作用在方法上
@Configuration
public class ConfigConditional {
@Bean(name = "xiaoming")
@Conditional(WindowsConfig.class)
public Student getStudent1(){
Student student = new Student();
student.setName("xiaoming");
student.setAge(18);
return student;
}
@Bean(name = "xiaohong")
public Student getStudent2(){
Student student = new Student();
student.setName("xiaohong");
student.setAge(17);
return student;
}
}
因为只在非windows系统注入xiaoming,因此输出为{xiaohong=Student(age=17, name=xiaohong)}。
@Conditional作用在类上
@Configuration
@Conditional(WindowsConfig.class)
public class ConfigConditional {
@Bean(name = "xiaoming")
public Student getStudent1(){
Student student = new Student();
student.setName("xiaoming");
student.setAge(18);
return student;
}
@Bean(name = "xiaohong")
public Student getStudent2(){
Student student = new Student();
student.setName("xiaohong");
student.setAge(17);
return student;
}
}
因为只在非windows系统注入xiaoming和xiaohong,因此输出为{}
@import
@Import注解用来帮助我们把一些需要定义为Bean的类导入到IOC容器里面。如果配置类在标准的springboot的包结构下,就是SpringbootApplication启动类在包的根目录下,配置类在子包下。就不需要使用@Import导入配置类,如果配置类在第三方的jar下,我们想要引入这个配置类,就需要@Import对其引入到工程中才能生效。因为这个时候配置类不再springboot默认的扫描范围内。
@Import源码注释里可以知道,value里面传递的Class会被Spring识别成为component组件。
@Import源码注释里面的一段说明,指出了@Import的用法:
- 导入一个@Configuration类
- 导入ImportSelector,ImportBeanDefinitionRegistrar的实现类
- 导入一个普通的类
/*
*<p>Provides functionality equivalent to the {@code <import/>} element in Spring XML.
* Allows for importing {@code @Configuration} classes, {@link ImportSelector} and
* {@link ImportBeanDefinitionRegistrar} implementations, as well as regular component
* classes (as of 4.2; analogous to {@link AnnotationConfigApplicationContext#register}).
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
/**
* {@link Configuration @Configuration}, {@link ImportSelector},
* {@link ImportBeanDefinitionRegistrar}, or regular component classes to import.
*/
Class<?>[] value();
}
@Import引入普通类
@Import引入普通的类可以帮助我们把普通的类定义为Bean。@Import可以添加在@SpringBootApplication(启动类)、@Configuration(配置类)、@Component(组件类)对应的类上。
定义Teacher类
@Data
public class Teacher {
private int age;
private String name;
}
在springboot的启动类@Import Teacher类,这个类就可以被其他类当做bean来引用。
输出结果Teacher(age=0, name=null)
@SpringBootApplication
@Import({Teacher.class})
public class SpringbootReviewApplication {
public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(SpringbootReviewApplication.class, args);
Teacher teacher = run.getBean(Teacher.class);
System.out.println(teacher);
}
}
//输出结果Teacher(age=0, name=null)
@Import引入配置类(@Configuration修饰的类)
@Import除了可以把普通的类定义为Bean,@Import还可以引入一个@Configuration修饰的类(引入配置类),从而把让配置类生效(配置类下的所有Bean添加到IOC容器里面去)如果配置类在标准的SpringBoot包结构下(SpringBootApplication启动类包的根目录下)。是不需要@Import导入配置类的,SpringBoot自动帮做了。上面的情况一般用于@Configuration配置类不在标准的SpringBoot包结构下面。所以一般在自定义starter的时候用到。
public class ImportDemo {
public void doSomething () {
System.out.println("ImportDemo.doSomething()");
}
}
@Configuration
@Import({ImportDemo.class})
public class ImportConfig{
@Bean
public Student returnOneStudent(){
return new Student();
}
}
@RestController
public class ImportDemoController {
@Autowired
private Student student;
@Autowired
private ImportDemo importDemo;
@RequestMapping("/importDemo")
public String demo() throws Exception {
importDemo.doSomething();
return "ImportDemo" + student.toString;
}
}
Springboot笔记<3> 组件注入注解@Conditional与@import的更多相关文章
- [读书笔记] 二、条件注解@Conditional,组合注解,元注解
一.条件注解@Conditional,组合注解,元注解 1. @Conditional:满足特定条件创建一个Bean,SpringBoot就是利用这个特性进行自动配置的. 例子: 首先,两个Condi ...
- springboot自动装配(3)---条件注解@Conditional
之前有说到springboot自动装配的时候,都是去寻找一个XXXAutoConfiguration的配置类,然而我们的springboot的spring.factories文件中有各种组件的自动装配 ...
- Spring Boot实战笔记(八)-- Spring高级话题(条件注解@Conditional)
一.条件注解@Conditional 在之前的学习中,通过活动的profile,我们可以获得不同的Bean.Spring4提供了一个更通用的基于条件的Bean的创建,即使用@Conditional注解 ...
- Spring学习笔记1—依赖注入(构造器注入、set注入和注解注入)
什么是依赖注入 在以前的java开发中,某个类中需要依赖其它类的方法时,通常是new一个依赖类再调用类实例的方法,这种方法耦合度太高并且不容易测试,spring提出了依赖注入的思想,即依赖类不由程序员 ...
- springboot拦截中自动注入的组件为null问题解决方法
一.写SpringUtil类来获取Springh管理的类实例,判断是否注入成功,如果没有注入成功重新获取注入 package com.util; import org.springframework. ...
- SpringBoot笔记(2)
一.容器功能 1.1 组件添加 1. @Configuration Full模式:获取对象时,首先在容器内搜索是否存在,如存在直接拿出 默认为Full模式,单例 配置类组件之间有依赖关系,方法会被调用 ...
- springboot(六)自动配置原理和@Conditional
官方参考的配置属性:https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#common-appl ...
- 对于springboot的几种注入方法的个人看法
最近在知乎上面看到一篇关于程序员面试的问题,面试官问我们一般有几种注入的方法,这几种注入的方法分别在什么时候运用比合理,当时我看到这个时候懵逼了,由于我自己也是刚刚接触springboot不久,所以就 ...
- springboot整合redis-sentinel支持Cache注解
一.前提 已经存在一个redis-sentinel集群,两个哨兵分别如下: /home/redis-sentinel-cluster/sentinel-1.conf port 26379 dir &q ...
- springboot用@Autowired和@PostConstruct注解把config配置读取到bean变成静态方法
springboot用@Autowired和@PostConstruct注解把config配置读取到bean变成静态方法 @SpringBootApplication public class Sen ...
随机推荐
- cxDBTreeList:最简单的节点图标添加方法
先在窗体上放ImageList关联到cxDBTreeList,在cxDBTreeList的GetNodeImageIndex事件中写如下: procedure cxDBTreeList1GetNode ...
- 一文速通Python并行计算:02 Python多线程编程-threading模块、线程的创建和查询与守护线程
一文速通 Python 并行计算:02 Python 多线程编程-threading 模块.线程的创建和查询与守护线程 摘要: 本文介绍了 Python threading 模块的核心功能,包括线程创 ...
- 推荐8款 .NET 开源、免费、实用的 Windows 效率软件
前言 今天大姚给大家推荐8款基于 .NET 开源.免费.实用的 Windows 效率软件,开发工作提升利器,希望可以帮助到有需要的小伙伴. DevToys DevToys是一个专门为开发者设计的Win ...
- [源码系列:手写spring] IOC第三节:Bean实例化策略InstantiationStrategy
主要内容 在第二节中AbstractAutowireCapableBeanFactory类中使用class.newInstance()的方式创建实例,仅适用于无参构造器. 大家可以测试一下,将第二节 ...
- C#之json字符串转xml字符串
留爪参考 using System.Xml; // using System.Text; // using System.Runtime.Serialization.Json; //JsonReade ...
- 如何优化和提高MaxKB回答的质量和准确性?
目前 ChatGPT.GLM等生成式人工智能在文本生成.文本到图像生成等在各行各业的都有着广泛的应用,但是由于大模型训练集基本都是构建于网络公开的数据,对于一些实时性的.非公开的或离线的数据是无法获取 ...
- 在web.xml下配置springmvc的核心控制器
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" ...
- Spring Boot Jpa封装快速构建Specification、OrderBy、Pageable的查询条件
1.简介 在我们使用JPA时,构建 Specification 查询条件时重复代码过多,而且需要大量的无效代码. 2.工具类提供的方法 2.1.自动构建规范 /** * 自动构建规范 * * @p ...
- 信息资源管理综合题之“X大师设计瓷砖给公司生产并检验和销售”
一.X大师是一位德高望重的设计大师,现在为A公司设计了一套陶瓷地砖,准备交由B公司进行批量生产.B企业按照GB/T 3810.13-1999陶瓷砖试验方法对该产品进行检测,检测合格,并推向市场 1.按 ...
- html_py
Sock.py import socket def handle_request(client): buf=client.recv(1024) client.send(bytes(&q ...