@Conditional 选择性添加Bean,(补充@Import注解)

@Conditional 注解用于给容器中选择性添加Bean
测试案例,根据不同的操作系统添加不同的Bean:

测试类

package com.liu.demo;

import java.util.Map;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.core.env.Environment;

import com.liu.demo.bean.Person;
import com.liu.demo.config.PersonConfig;

public class IocTest {
	@Test
	public void test02() {
		ApplicationContext applicationContext = new AnnotationConfigApplicationContext(PersonConfig.class);
		//获取系统运行环境
		//getEnvironment 返回与给定key关联的属性值,如果不能解析key,则返回null。
		Environment environment = applicationContext.getEnvironment();
		String property = environment.getProperty("os.name");
		//如果是win10系统,则输出Windows 10
		System.out.println("当前系统是:" + property);
		
		//getBeanNamesForType 返回与给定类型(包括子类)匹配的bean的名称,根据bean定义或FactoryBeans中getObjectTypein的值判断。
		String[] beanNames = applicationContext.getBeanNamesForType(Person.class);
		for (String beanName : beanNames) {
			System.out.println("包含的所有Bean的名称" + beanName);
		}
		//getBeansOfType 返回与给定对象类型(包括子类)匹配的bean实例,从bean定义或FactoryBeans中getObjectType的值判断。
		Map<String, Person> beans = applicationContext.getBeansOfType(Person.class);
		System.out.println("包含的所有Bean的实例:" + beans);
		
	}
}

Person类

Person对象的一些属性

package com.liu.demo.bean;

public class Person {

	private String name;
	
	private Integer age;
	
	private String sex;

	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + ", sex=" + sex + "]";
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	public String getSex() {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

	public Person(String name, Integer age, String sex) {
		super();
		this.name = name;
		this.age = age;
		this.sex = sex;
	}

	public Person() {
		super();
		// TODO Auto-generated constructor stub
	}
	
}

配置文件PersonConfig

@Configuration 表明这个类声明了一个或多个@Bean方法,交给Spring容器处理,以便在运行时为这些bean生成bean定义和服务请求,
@Conditional 指示只有当所有指定条件匹配时,组件才有资格注册。传入参数为判断条件,条件是可以在注册bean定义之前通过编程确定的任何状态,此处编写了两个类WindowsConditionLinuxCondition,继承了Condition接口,并实现matches方法

package com.liu.demo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;

import com.liu.demo.bean.Person;
import com.liu.demo.condition.LinuxCondition;
import com.liu.demo.condition.WindowsCondition;

@Configuration
public class PersonConfig {
	
	@Bean
	public Person person() {
		return new Person("zhangsan", 18, "男");
	}

	/**
	 * @Conditional 注解可用于方法、类上,满足条件后添加Bean
	 * @return
	 */
	@Conditional(WindowsCondition.class)
	@Bean
	public Person person01() {
		return new Person("001", 18, "男");
	}
	
	@Conditional(LinuxCondition.class)
	@Bean
	public Person person02() {
		return new Person("002", 18, "男");
	}

}

判断条件(WindowsCondition类、LinuxCondition类)

package com.liu.demo.condition;

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;

public class WindowsCondition implements Condition{

	/**
	 * ConditionContext 上下文信息作为判断条件
	 * AnnotatedTypeMetadata 定义对特定类型(classor方法)的注释的访问,其形式不一定需要加载类。
	 */
	@Override
	public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
		// TODO 判断是否是Windows系统
		Environment environment = context.getEnvironment();
		String property = environment.getProperty("os.name");
		if(property.contains("Windows")) {
			return true;
		}
		return false;
	}

}

matches 方法中的参数context 可以获取到的内容有 获取bean工厂、获取类加载器、获取当前环境、获取bean定义的注册表等等 ,如下所示

package com.liu.demo.condition;

import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;

public class LinuxCondition implements Condition{

	/**
	 * ConditionContext 上下文信息作为判断条件
	 * AnnotatedTypeMetadata 定义对特定类型(classor方法)的注释的访问,其形式不一定需要加载类。
	 */
	@Override
	public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
		//context可获取到的内容
		//获取bean工厂
		ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
		//获取类加载器
		ClassLoader classLoader = context.getClassLoader();
		//获取当前环境
		Environment environment = context.getEnvironment();
		/**
		 * 获取bean定义的注册表
		 * 可用于判断是否包含某个bean
		 * 可以添加bean
		 * 等等
		 */
		BeanDefinitionRegistry registry = context.getRegistry();
		
		// TODO 判断是否是Linux系统
		String property = environment.getProperty("os.name");
		if(property.contains("Linux")) {
			return true;
		}
		return false;
	}

}

结果

当前系统是:Windows 10
包含的所有Bean的名称person
包含的所有Bean的名称person01
包含的所有Bean的实例:{person=Person [name=zhangsan, age=18, sex=男], person01=Person [name=001, age=18, sex=男]}

补充 @Import注解

@Import 注解有类似的功能,传入一个实现了ImportSelector 接口的类,该类实现selectImports 方法,返回要导入的全类名,在实现的selectImports 方法中可以进行自定义的处理
示例:

package com.liu.demo.selecter;

import java.util.Set;

import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;

public class MyImportSelector implements ImportSelector{

	/**
	 * AnnotationMetadata 注释元数据
	 */
	@Override
	public String[] selectImports(AnnotationMetadata importingClassMetadata) {
		// TODO Auto-generated method stub
		//获取注释类型 eg:[org.springframework.context.annotation.Configuration, org.springframework.context.annotation.Import]
		Set<String> allAnnotationAttributes = importingClassMetadata.getAnnotationTypes();
		System.out.println("---" + allAnnotationAttributes.toString());
		//返回全类名
		return new String[] {"com.liu.demo.bean.Red"};
	}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java8新特性及实战视频教程完整版Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。 Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。使用Lambda 表达式可以使代码变的更加简洁紧凑。Java8实战视频-01让方法参数具备行为能力Java8实战视频-02Lambda表达式初探Java8实战视频-03Lambda语法精讲Java8实战视频-04Lambda使用深入解析Java8实战视频-05Lambda方法推导详细解析-上.wmvJava8实战视频-06Lambda方法推导详细解析-下Java8实战视频-07Stream入门及Stream在JVM中的线程表现Java8实战视频-08Stream知识点总结Stream源码阅读Java8实战视频-09如何创建Stream上集Java8实战视频-10如何创建Stream下集.wmvJava8实战视频-11Stream之filter,distinct,skip,limit,map,flatmap详细介绍Java8实战视频-12Stream之Find,Match,Reduce详细介绍Java8实战视频-13NumericStream的详细介绍以及和Stream之间的相互转换Java8实战视频-14Stream综合练习,熟练掌握API的用法Java8实战视频-15在Optional出现之前经常遇到的空指针异常.wmvJava8实战视频-16Optional的介绍以及API的详解Java8实战视频-17Optional之flatMap,综合练习,Optional源码剖析Java8实战视频-18初识Collector体会Collector的强大Java8实战视频-19Collector使用方法深入详细介绍-01Java8实战视频-20Collector使用方法深入详细介绍-02Java8实战视频-21Collector使用方法深入详细介绍-03.wmvJava8实战视频-22Collector使用方法深入详细介绍-04Java8实战视频-23Collector原理讲解,JDK自带Collector源码深度剖析Java8实战视频-24自定义Collector,结合Stream的使用详细介绍Java8实战视频-25Parallel Stream编程体验,充分利用多核机器加快计算速度Java8实战视频-26Fork Join框架实例深入讲解Java8实战视频-27Spliterator接口源码剖析以及自定义Spliterator实现一个Stream.wmvJava8实战视频-28Default方法的介绍和简单的例子Java8实战视频-29Default方法解决多重继承冲突的三大原则详细介绍Java8实战视频-30多线程Future设计模式原理详细介绍,并且实现一个Future程序Java8实战视频-31JDK自带Future,Callable,ExecutorService介绍Java8实战视频-32实现一个异步基于事件回调的Future程序.wmvJava8实战视频-33CompletableFuture用法入门介绍Java8实战视频-34CompletableFuture之supplyAsync详细介绍Java8实战视频-35CompletableFuture流水线工作,join多个异步任务详细讲解Java8实战视频-36CompletableFuture常用API的重点详解-上Java8实战视频-37CompletableFuture常用API的重点详解-下Java8实战视频-38JDK老DateAPI存在的问题,新的DateAPI之LocalDate用法及其介绍.wmvJava8实战视频-39New Date API之LocalTime,LocalDateTime,Instant,Duration,Period详细介绍Java8实战视频-40New Date API之format和parse介绍

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值