当前位置: 首页 > 网络应用技术

春季系列@Contitional控制Bean通过条件的注册

时间:2023-03-08 01:13:54 网络应用技术

  Ali P7提出的问题(我当时只知道第一个):

  @Conditional注释仅可从Spring4.0开始。它可以在任何类型或方法上使用。它可以通过@Conditional注释进行配置。当满足所有条件时,Spring Fancer.deal将接受以@Conditional标记的目标。

  例如,您可以控制BEAN是否需要通过@Conditional注册,并控制以@Configuration标记的配置类。

  效果就像这种代码一样,相当于在弹簧容器分析目标面前添加条件判断:

  @Conditional源代码:

  该注释只有一个值参数,条件类型的数组,条件是指示有条件判断的接口。内部有一种返回真或错误的方法。建立所有条件后,建立@条件的结果。

  让我们看一下条件接口。

  用于表示条件判断的源代码如下:

  它是一个功能接口,只有一种匹配方法,用于确定是否建立了条件。两个参数:

  该界面提供了一些常用的方法,可用于在弹簧容器中获取各种信息。查看源代码:

  春季对配置类的处理主要分为两个阶段:

  将获得配置类的一批信息,以及一些需要注册的豆类

  注册由配置类分析阶段获得的配置类,并注册需要注册到弹簧容器的BEAN

  课程中的以下注释之一属于配置类:

  确定类是否是配置类,是否是以下方法。如果您有兴趣,可以看看:

  org.springframework.context.annotation.configurationClassutils#isConfigurationCandidate

  春季处理这两个过程将进行,直到对所有配置类的分析和所有BEAN的注册。

  源代码位置:

  整个过程大致如下:

  您可以从上述过程中学习:

  配置类是由Spring处理的:有两个阶段:配置类解析阶段和BEAN注册阶段(配置类注册为弹簧容器)。

  如果条件接口的实现类用作配置类@conditional,则此条件对于两个阶段都有效。目前,在条件下无法在某个阶段对其进行精心控制。他进行了分析,但他不能让他注册。目前,需要另一个接口:配置条件

  查看此接口的源代码:

  与条件接口相比,配置条件接口具有GetConfigurathphase方法,以指定条件判断的阶段。当配置类解析时创建配置类时,是过滤还是过滤。

  在配置类上使用@contitional。当该注释指定的条件是错误的情况时,Spring会跳过处理类。

  自定义条件类:

  我们可以随意使用比赛方法。在这里,我们直接返回false以获得演示效果。

  让我们在配置类上使用上述条件。目前,配置类将失败,如下:

  @1:使用自定义条件类

  @2:通过@Bean标记此方法,如果成功分析了此配置类,则名称方法的返回值将被注册为bean到spring容器

  对于测试类,启动弹簧容器,加载MainConfig3配置类,如下:

  在Test3中,字符串类型的bean是在设施中获得的,并且没有输出运行test3。

  我们可以在mainconfig3上删除@conditional,然后再次运行输出:

  让我们有一个配置类,如下:

  以上两种方法使用@BEAN注释来定义2个bean。该名称方法使用@conditional注释。该条件将在注册到容器的名称名称之前进行判断。当条件为真时,名称为本次将注册到容器中。

  在条件测试中,添加了一个新的测试用例以加载上述配置类,并且所有bean输出均在经文中获得。代码如下:

  运行输出:

  您可以看到在容器中仅注册一个地址,并且名称的名称未注册。

  Iservice接口的两个实现类Service1和Service1。这两个类将放置在两个配置类中,以通过 @bean.register注册到容器的容器中。

  您可以对@bean标记的两种方法添加条件限制。当容器中没有Iservice类型的bean时,该方法定义的bean将注册到容器中。让我们看下面的代码实现。

  有条件的判断课:诉讼

  在上面的匹配方法中,您将查看容器中是否存在Iservice类型的bean,并在不存在时返回true。

  iservice接口

  有2个实施类服务1接口

  服务2

  参加负责注册服务的配置类1

  @1:使用条件之前的方法

  让我们让另一个配置类负责注册服务2到容器

  @1:使用条件之前的方法

  进入总配置类,导入另外两个配置类

  @1:通过@Import的另外两个配置类

  让我们有一个新的方法条件测试。在该方法中,在附件中获取iservice型bean,然后输出:

  运行输出:

  可以看出,容器中只有一个iservice型bean。

  您可以删除@conditional @conditional标记为@bean,然后输出操作:

  目前没有有条件的限制,将向容器注册2个服务。

  当我们进行项目时,会有开发环境,测试环境和在线环境。每个环境中的一些信息都不同。例如。

  @1:请注意,此注释更为特别。该注释使用上面的@Conditional注释。这个地方使用自定义条件类:环境

  @2:指示环境的枚举定义了3个环境

  @3:此参数使用指定的环境

  上述注释将在不同环境中的配置类中使用一段时间

  让三个配置类在不同的环境中生效,并将在这些配置类上方使用@envconditional注释来建立条件限制。

  在每个配置类中,通过@Bean定义一个名为名称的bean,可以有效地确定哪个配置类将通过输出此BEAN生效。

  让我们看一下3个配置类的代码

  测试环境配置类

  @1指定的测试环境

  开发环境配置

  @1:指定的开发环境

  生产环境配置

  @1:指定的生产环境

  条件类将分析配置类@envconditional注释以获取环境信息。

  然后将与当前环境进行比较,决定返回真或错误,如下:

  @1:使用用于指定当前用途的环境假定当前的开发环境是假定的。我们可以在将来任意玩。例如,将它们放在配置文件中,这对于演示效果很方便。

  您可以看到开发环境已生效。

  修改环境代码并切换到生产环境:

  再次运行test2方法输出:

  生产环境配置已生效。

  当@condtions中的值指定多个条件时,默认情况下将按顺序执行,或者代码使用效果。

  以下代码定义了3个条件,每个条件的匹配方法将输出当前类名称,然后同时使用配置类上的这3个条件:

  让我们服用测试案例

  运行输出:

  上面有多行输出,因为Spring分析了整个配置类,并且有几个位置将执行条件判断。

  我们只需要注意前三行。可以看出,输出的属性与@conditional中的值值相同。

  自定义条件可以实现优先顺序的接口或继承有序接口,或使用@Order注释通过这些指定这些条件的优先级。

  排序规则:首先,遵循优先顺序,然后根据订单的值进行排序;

  查看案例代码:

  @1:条件1指定 @order的顺序,值为1

  @2:条件2通过实现订单接口来指定订单,@3:getOrder方法返回1

  @4:条件3实现优先顺序的接口。要实现此界面,您需要重写GetOrder方法并返回1000

  @5:康复序列是1、2、3

  根据排序规则,优先顺序将在提前排名,然后将按顺序提升订单。最后,可以是:

  让我们以测试案例查看是否分析了效果:

  运行test6,输出的一部分如下:

  结果与我们的分析一致。

  配置条件使用较少。许多地方不会引入此问题。条件接口基本上可以满足99%的需求,但是配置条件接口在Springboot中使用。

  通过解释很难理解配置条件。

  通过@Import介绍了其他两个配置类

  将弦类型的豆子在水内进行,然后输出。

  当容器中有一种服务时,BeanConfig2生效。

  这很简单,只需添加条件即可。容器的内部判断中有一个服务类型的豆子,然后继续

  上面的代码非常简单,判断容器中是否有iservice类型。

  没有输出

  在文章的前面,我们说配置类的处理将依次进行两个阶段:配置类分析阶段和BEAN注册阶段,条件接口类型的条件对于这两个阶段将有效。在分析阶段,容器仍在进行服务中,在bean注册阶段期间,配置类中@Bean注释定义的bean,bean将注册到弹簧容器,因此BeanConfig2无法将服务视为解析中的bean,舞台,因此被拒绝拒绝

  目前,我们需要使用ConfigurationCondition使条件判断仅在BEAN注册阶段工作。

  @1:指定条件在BEAN注册阶段,此条件有效

  匹配方法中的内容被直接复制以判断规则不变。

  目前,bean的名称已输出。

  您可以尝试在beanconfig1中的服务方法上删除@bean。目前,该服务将不注册到容器中。然后运行test7,您会发现没有输出。目前,BeanConfig2将失败。

  判断BEAN中不存在的问题通常使用配置条件的接口,阶段为:register_bean,以便在BEAN注册阶段执行条件判断。

  熟悉Springboot,有许多注释,例如@conditionxxx。您可以看到这些注释。他们中的许多已经实现了配置调节接口。

  @conditional注释由以下类处理

  这是另一个类别。已经说了很多次。一个非常重要的类别。每个人都会下降并击败此类别的源代码,这更流畅地理解。

  所有路人的案例 - 毕竟将在此上放置。每个人都可以继续关注动态。