Condition:满足某个特定条件的情况下创建bean

条件化配置bean:

a:@Conditional 指定一个class ,它指明了通过条件对比的类。如果没有指定class则通过Conditon接口进行条件对比:

b:@Conditional 指定的类可以是任意实现了Condition接口的类

c:指定的类需要重写matches方法

1.例子1:

@Bean
@Conditional(MagicExistsConditon.class) //条件化的创建bean
public MagicBean magicBean(){
return new MagicBean();
}

Condition接口:

public interface Condition{
boolean matches(ConditionContext context,AnnotatedTypeMetadata metadata);
}

MagicExistsConditon实现类:

 public class MagicExistsCondition implements Condition{
public boolean matches(ConditionContext context,
AnnotatedTypeMetadata metadata)
Environment env = context.getEnvironment();
return env.containsProperty("magic");
}
}

例子1,Conditional注解指定了实现类作为条件,如果环境中包含magic属性,则会创建magicBean;

ConditionContext 是一个接口:

 public interface ConditionContext{
BeanDefinitionRegistry getRegistry();
ConfigurableListableBeanFactory getBeanFactory();
Environment getEnvironment();
ResourceLoader getResourceLoader();
ClassLoader getClassLoader();
}

通过ConditionContext可以检查bean的定义;

通过BeanFactory,可以检查bean是否存在,甚至探查bean的属性;

检查环境变量是否存在以及它的值是什么;

ResourceLoader所加载 的资源;

ClassLoader加载并检查类是否存在;

AnnotatedTypeMetadata接口:能够让我们检查带有@Bean注解的方法上还有什么其他的注解;

publlic interface AnnotatedTypeMetadata{
boolean isAnnotated(String annotationType);
Map<String,Object> getAnnotationAttributes(String annotationType);
Map<String,Object> getAnnotationAttributes(String annotationType,boolean classValuesAsString);
MultiValueMap<String,Object> getAllAnnotationAttributes(
String annotationType);
MultiValueMap<String,Object> getAllAnnotationAttributes(String annotationType,boolean classValuesAsString);
}

a:判断是否还有其他注解;

b:检查@Bean注解的方法上其他注解的属性;

例子2:@Profile注解

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.Type,ElementType.METHOD})
@Documented
@Conditional(ProfileCondition.class)
public @interface Profile{
String[] value();
}

Profile注解使用了@Conditional注解。

通过查看ProfileConditon的源码,可以发现,它借助ConditonContext得到Environment来检查该Profile是否处于激活状态。

public boolean matches(ConditionContext contex,AnnotatedTypeMeatadata metadata){
if(context.getEnvironment() != null){
MultiValueMap<String,Object> attrs = metadata.getAllAnnotationAttributes(Profile.class.getName());
if(atts != null){
for(Object value: attrs.get("value")){
if(context.getEnvironment().acceptsProfiles((String[]) value)){
return true;
}
return false;
}
}
return true;
}
}

例子3:处理自动装配的歧义性:

当通过@Autowared注入一个接口的时候,如果该接口有多个实现类的时候,spring,不知道该注入那个实现类的代理。

解决方法:

a:通过在实现类上添加注解@Primary与@Component同时使用,代表当出现多个的时候,此类优先注入。

b:存在多个首选的时候,通过@Qualifier注解,@Qualifier(“iceCream”),value的值代表想要注入的bean的ID

c:出现多个ID相同的时候,创建自定义限定符,即@Qualifier(“iceCream”),自定义value的值,如下,cold即自定义的限定符

@Component
@Qualifier("cold")
public class IceCream implements Dersert{......}

d:当出现重复的自定义符时,通过自定义限定符注解,自定义一个注解,加上@Qualifier注解,则自定义的注解也有了Qualifier的功能。当出现自定义限定符重复的时候,可以通过添加多个自定义限定符注解,实现要注入的是哪个bean

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.Constructor,ElementType.FILED,ElementType.METHOD,ElementType.TYPE})
@Qualifier
public @interface cold{.....}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.Constructor,ElementType.FILED,ElementType.METHOD,ElementType.TYPE})
@Qualifier
public @interface creamy{.....}

  

(二)spring 高级装配-Condition -条件化的bean的更多相关文章

  1. Spring入门(六):条件化的bean

    1. 概念 默认情况下,Spring中定义的bean在应用程序启动时会全部装配,不管当前运行的是哪个环境(Dev,QA或者Prod),也不管当前运行的是什么系统(Windows或者Linux),但有些 ...

  2. Spring 梳理-profile与条件化定义bean

    定义profile <beans> //root <beans profile="dev"> <bean id=.../> </beans ...

  3. @Condition 条件化注册Bean

    看<Spring源码深度解析>笔记 1.@Condition: 按照一定的条件进行判断,满足条件给容器中注册bean:实例: 根据系统给容器中注册Bean,如果是windows注册(“bi ...

  4. 第3章—高级装配—条件化的Bean

    条件化的Bean 通过活动的profile,我们可以获得不同的Bean.Spring 4提供了一个更通用的基于条件的Bean的创建方式,即使用@Conditional注解. @Conditional根 ...

  5. Spring高级装配

    Spring高级装配 目录 一.Profile(根据开发环境创建对应的bean) 二.条件化的创建bean(根据条件创建bean) 三.处理自动装配歧义性(指定首选bean.限定符限制bean) 四. ...

  6. Spring高级装配bean

    目录 spring profile 条件化的bean声明 自动装配与歧义性 bean的作用域 Spring表达式语言 一.环境与profile 配置profile  bean 在软件开发的时候,有一个 ...

  7. Spring高级装配(一) profile

    Spring高级装配要学习的内容包括: Spring profile 条件化的bean声明 自动装配与歧义性 bean的作用域 Spring表达式语言 以上属于高级一点的bean装配技术,如果你没有啥 ...

  8. 【Java Web开发学习】Spring4条件化的bean

    [Java Web开发学习]Spring4条件化的bean 转载:https://www.cnblogs.com/yangchongxing/p/9071960.html Spring4引入了@Con ...

  9. 002Conditional条件化创建bean

    01.条件化配置bean @Bean @Conditional(MagicExistsCondition.class)---->条件化创建bean public MagicBean magicB ...

随机推荐

  1. 小白学Python(5)——python-pptx简单应用

    python-pptx允许您创建新的演示文稿以及对现有演示文稿进行更改. 实际上,它只允许您对现有演示文稿进行更改:只是,如果您从一个没有幻灯片的演示文稿开始,一开始感觉就像是从头开始创建一个幻灯片. ...

  2. Mina各组件介绍

    Mina各组件介绍 上一篇文章已经系统的介绍了Mina的运行流程,Apache推出的Mina性能上很是高效,上章节我们知道内部有很多的类,各个类之间的依赖也是很多,他们之家都是相互依赖. 下面主要看看 ...

  3. 『深度应用』NLP机器翻译深度学习实战课程·壹(RNN base)

    深度学习用的有一年多了,最近开始NLP自然处理方面的研发.刚好趁着这个机会写一系列NLP机器翻译深度学习实战课程. 本系列课程将从原理讲解与数据处理深入到如何动手实践与应用部署,将包括以下内容:(更新 ...

  4. EOS源码分析:transaction的一生

    最近在处理智能合约的事务上链问题,发现其中仍旧有知识盲点.原有的认识是一个事务请求会从客户端设备打包签名,然后通过RPC传到非出块节点,广播给超级节点,校验打包到可逆区块,共识确认最后变为不可逆区块. ...

  5. Ansible实践总结

    Ansible playbook 根据条件动态设置变量 首先新建 inventory,主机列表如下: node-01 ansible_host=192.168.64.30 node-02 ansibl ...

  6. Liunx学习总结(六)--进程

    进程概述 简单来讲程序是一个包含可以执行代码的静态的文件.进程是一个开始执行但是还没有结束的程序的实例.当程序被系统调用到内存以后,系统会给程序分配一定的资源(内存,设备等等)然后进行一系列的复杂操作 ...

  7. unity编辑器扩展_05(删除游戏对象并具有撤回功能)

    代码: [MenuItem("Tools/Delete",false,1)]    static void Delete()    {        GameObject[] go ...

  8. Java - 集合之间的关系和区别

    1.Java集合关系图: 2.List.Map.Set区别: ① List ArrayList LinkedList Vector Advantage Search Insert.Delete Syn ...

  9. IDEA-Maven项目的jdk版本设置

    在 Intellij IDEA 中,我们需要设置 Settings 中的 Java Compiler 和 Project Structure 中的 Language Level 中的 jdk 版本为自 ...

  10. Delphi - Indy TIdHTTP方式创建程序外壳 - 实现可执行程序的自动升级

    Delphi 实现可执行程序的自动升级 准备工作: 1:Delphi调用TIdHTTP方式开发程序,生成程序打包外壳 说明:程序工程命名为ERP_Update 界面布局如下: 代码实现如下: unit ...