当每个开发者初始化一套服务时,可能会因不同的系统或不同的Java版本相容性问题进而产生不同的Bean元件,故在此Spring 框架提供了多种条件判断各种Bean是否要建立於IoC配置连接池中,并以设计好18种相容於既有Spring 框架的Conditional注解(Annotation)提供开发者做延用,若没有开发者预期的Conditional注解(Annotation)类别元件,开发者可自行进行继承实作Condition注解类别中的matches方法,进而去判断相关的Bean是否建立於Spring IoC配置连接池中,。
@Conditional是Spring 4之後新提供的注解,主要是用来判断是否注册各类型的Bean类别元件接口,每个Conditional注解都会配置一个条件,当满足此条件会将此Bean类别元件注册於IoC配置连接池中,此注解我们可配置在类别(Class)与方法(Method)上,在於Conditional注解上分为两种,一种是原生Spring提供,另一种为客制化动态配置类别,接下来我们将依照下方程序区段进行延伸讨论。
- 原生Condition 注解判断类型,我们将提供,我们将针对这19种Spring框架所提供的Conditional进行分析
1.1 ConditionalOnBean : IoC配置持已存在指定的Bean类别元件条件下,才可以建立此Bean类别元件。
@Bean("Pomeranian")
@ConditionalOnBean(name="Weisting")
public Dog getAnimalOfDog() {
Dog dog = new Dog();
dog.setName("Pomeranian");
dog.setType("Dog");
dog.setSound("Wong ! Wong ! Wong !");
return dog;
}
1.2 ConditionalOnClass : 目前专案存在指定的类别存在下,才可建立此Bean类别元件。
@Bean("TBaby")
@ConditionalOnClass(Animal.class)
public Turtle getAnimalOfTurtle() {
Turtle turtle = new Turtle();
turtle.setName("TBaby");
turtle.setType("Turtle");
turtle.setBehavior("Climb");
return turtle;
}
1.3 ConditionalOnMissingBean : IoC配置持不存在指定的Bean类别元件条件下,才可以建立此Bean类别元件。
@Bean("malzis")
@ConditionalOnMissingBean(name="Pomeranian")
public Dog getAnimalOfDogWithMalzis() {
Dog dog= new Dog();
dog.setName("malzis");
dog.setType("Dog");
dog.setSound("Wong ! Wong ! Wong !");
return dog;
}
1.4 ConditionalOnMissingClass : 目前专案不存在指定的类别存在下,才可建立此Bean类别元件。
@Bean("lucky")
@ConditionalOnMissingClass(value = {"sw.spring.conditional.model.Cat"})
public Dog getAnimalOfDogWithLucky() {
Dog dog= new Dog();
dog.setName("lucky");
dog.setType("Dog");
dog.setSound("Wong ! Wong ! Wong !");
return dog;
}
1.5 ConditionalOnWebApplication : 目前专案为一套WEB开发项目下,才可建立此Bean类别元件。
@Bean("husky")
@ConditionalOnWebApplication
public Dog getAnimalOfDogWithHusky() {
Dog dog= new Dog();
dog.setName("husky");
dog.setType("Dog");
dog.setSound("Wong ! Wong ! Wong !");
return dog;
}
1.6 ConditionalOnNotWebApplication : 目前专案不是为一套WEB开发项目下,才可建立此Bean类别元件。
@Bean("ghost")
@ConditionalOnNotWebApplication
public Dog getAnimalOfDogWithGhost() {
Dog dog= new Dog();
dog.setName("ghost");
dog.setType("Dog");
dog.setSound("Wong ! Wong ! Wong !");
return dog;
}
1.8 ConditionalOnProperty : 目前专案已存在指定的Properties下,才可建立此Bean类别元件。
@Bean("Bernard")
@ConditionalOnProperty(prefix = "sw.spring.conditional",name = "assert",havingValue = "true")
public Turtle getAnimalOfTurtleWithBernard() {
Turtle turtle = new Turtle();
turtle.setName("Bernard");
turtle.setType("Turtle");
turtle.setBehavior("Climb");
return turtle;
}
1.9 ConditionalOnJava : 目前专案已存在Java指定的版本下,才可建立此Bean类别元件。
@Bean("schnauzer")
@ConditionalOnJava(JavaVersion.FIFTEEN)
public Dog getAnimalOfTurtleWithSchnauzer() {
Dog dog= new Dog();
dog.setName("schnauzer");
dog.setType("Dog");
dog.setSound("Wong ! Wong ! Wong !");
return dog;
}
1.10 ConditionalOnExpression : 满足SpEL表达式作为判断条件下,才可建立此Bean类别元件。
@Bean("dylan")
@ConditionalOnExpression("#{'true'.equals(environment['sw.spring.conditional.assert'])}")
public Dog getAnimalOfDogWithDylan() {
Dog dog = new Dog();
dog.setName("dylan");
dog.setType("Dog");
dog.setSound("Wong ! Wong ! Wong !");
return dog;
}
1.11 ConditionalOnResource : 目前专案已存在指定的资源类别,才可建立此Bean类别元件。
@Bean("resource")
@ConditionalOnResource( resources = "classpath:/application.properties")
public Dog getAnimalOfDogWithResource() {
Dog dog = new Dog();
dog.setName("resource");
dog.setType("Dog");
dog.setSound("Wong ! Wong ! Wong !");
return dog;
}
1.12 ConditionalOnSingleCandidate : 在IoC配置池中存在指定的Bean类别元件,且为主要首选的Bean类别元件,才可建立此Bean类别元件。
@Bean("robert")
@ConditionalOnSingleCandidate(ApplicationBoot.class)
public Dog getAnimalOfDogWithSingleCandidate() {
Dog dog = new Dog();
dog.setName("robert");
dog.setType("Dog");
dog.setSound("Wong ! Wong ! Wong !");
return dog;
}
1.13 ConditionalOnRepositoryType : 当特定类别有指定的存储库类型(RepositoryType)存在下[其类型分为:AUTO、IMPERATIVE、NONE及REACTIVE其四种],才可建立此Bean类别元件。
@Bean("JPA-Repository")
@ConditionalOnRepositoryType(store = "JPA-Repository",type= RepositoryType.NONE)
public Turtle getAnimalOfFlyTurtle() {
Turtle turtle = new Turtle();
turtle.setName("JPA-Repository");
turtle.setType("Turtle");
turtle.setBehavior("Climb");
return turtle;
}
1.14 ConditionalOnWarDeployment : 目前专案只在war包中运作中,才可建立此Bean类别元件。
@Bean("war")
@ConditionalOnWarDeployment
public Dog getAnimalOfDogWithJNDI() {
Dog dog = new Dog();
dog.setName("war");
dog.setType("Dog");
dog.setSound("Wong ! Wong ! Wong !");
return dog;
}
1.15 ConditionalOnJndi : 若JNDI InitialContext 中的存在可用和可以查找指定位置的条件,才可建立此Bean类别元件。
1.16 ConditionalOnCloudPlatform : 若此服务建立在云端平台服务上,目前支援仅Cloud Foundry platform、Heroku platform、SAP Cloud platform及 Kubernetes platform其四项云端平台,才可建立此Bean类别元件。
1.17 ConditionalOnDefaultWebSecurity : 如果系统有预设Web 安全的默认配置。 且此设定会依赖Spring Framework Security套件,其套件为规范条件各类使用者运用何种身份验证,才可建立此Bean类别元件。
1.18 ConditionalOnMissingFilterBean : 某个FilterBean元件类别的对象不存在时,才可建立此Bean类别元件。
1.19 ConditionalOnEnabledResourceChain : 会依据ResourceProperties中进行判断三项资源是否启用与存在,分别为spring.resources.chain.strategy.fixed.enabled、spring.resources.chain.strategy.content.enabled及spring.resources.chain.enabled,若不存在,则判断是否存在org.webjars.WebJarAssetLocator套件,进行判断资源是否匹配,才可建立此Bean类别元件。
2.若要客制化一个Conditional类别,必须建立一个类别并进行继承与实作,并将此类别条件配置於该Conditional注解中,相关片段程序码如下。
public class MacCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return context.getEnvironment().getProperty("os.name").contains("Mac");
}
}
---
@Bean("machine")
@Conditional(MacCondition.class)
public Dog getAnimalOfDogWithMachine() {
Dog dog = new Dog();
dog.setName("machine");
dog.setType("Dog");
dog.setSound("Wong ! Wong ! Wong !");
return dog;
}
在Conditional注解的结构中,必须预设配置一个继承Condition介面的类别元件,此类别会实作matches的一个方法,透过此方法进行判断是否符合条件,故无论是否为Spring框架所提供的各类Conditional注解,或开发者自身客制化的Condition条件逻辑方法,都会经由主要的核心注解(Conditional)进行请求判断(invoke)。
图一 Conditional 架构图
Run test task
gradle test
Run open result html
open ./build/reports/tests/test/index.html
Test Class Sample
Test Details.
<<: [重构倒数第10天] - 行动装置上面的 Touch 跟 Click
>>: 【在 iOS 开发路上的大小事-Day09】将常用的 Function 写成一个 class,让各个档案都能使用
相信大家都可以把 WordPress 架起来了,因此就从安装 WooCommerce 开始吧! 安装...
在 EP13 - 灾难演练,重建你的 VPC, 我们在重建 VPC 之前, 有带着大家怎麽进行单次备...
在这里我就直接开门见山丢上我最终画面了 网站(再过几天服务应该就会到期) http://crypto...
Hashicorp Vault: Diagnose Vault server 这是Vault 1.8...
Grid 今天要讲解的是Grid排版的部分,如果是有使用过bootstrap的经验的朋友,其实它的逻...