您好,欢迎访问一九零五行业门户网

Spring Boot中的条件判断的介绍(附代码)

本篇文章给大家带来的内容是关于spring boot中的条件判断的介绍(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。
spring boot中的那些conditional
spring boot中为我们提供了丰富的conditional来让我们得以非常方便的在项目中向容器中添加bean。本文主要是对各个注解进行解释并辅以代码说明其用途。
所有conditionalonxxx的注解都可以放置在class或是method上,如果方式在class上,则会决定该class中所有的@bean注解方法是否执行。
@conditional下面其他的conditional注解均是语法糖,可以通过下面的方法自定义conditionalonxxx
conditional注解定义如下,接收实现condition接口的class数组。
public @interface conditional {    class<? extends condition>[] value();}

而condition接口只有一个matchs方法,返回是否匹配的结果。
public interface condition {    boolean matches(conditioncontext context, annotatedtypemetadata metadata);}

通过操作系统进行条件判断,从而进行bean配置。当window时,实例化bill的person对象,当linux时,实例化linus的person对象。
//linuxcondition,为方便起见,去掉判断代码,直接返回true了public class linuxcondition implements condition {    @override    public boolean matches(conditioncontext conditioncontext, annotatedtypemetadata annotatedtypemetadata) {        return true;    }}

//windowscondition,为方便起见,去掉判断代码,直接返回false了public class windowscondition implements condition {    @override    public boolean matches(conditioncontext conditioncontext, annotatedtypemetadata metadata) {        return false;    }}

@data@tostring@allargsconstructor@noargsconstructorpublic class person {    private string name;    private integer age;}

//配置类@configurationpublic class beanconfig {    @bean(name = bill)    @conditional({windowscondition.class})    public person person1(){        return new person(bill gates,62);    }    @bean(linus)    @conditional({linuxcondition.class})    public person person2(){        return new person(linus,48);    }}

public class apptest {    annotationconfigapplicationcontext applicationcontext = new annotationconfigapplicationcontext(beanconfig.class);    @test    public void test(){        string osname = applicationcontext.getenvironment().getproperty(os.name);        system.out.println(当前系统为: + osname);        map<string, person> map = applicationcontext.getbeansoftype(person.class);        system.out.println(map);    }}

输出的结果:
当前系统为:mac os x
{linus=person(name=linus, age=48)}@conditionalonbean & @conditionalonmissingbean这两个注解会对bean容器中的bean对象进行判断,使用的例子是配置的时候,如果发现如果没有computer实例,则实例化一个备用电脑。
@data@allargsconstructor@tostringpublic class computer {    private string name;}

@configurationpublic class beanconfig {    @bean(name = notebookpc)    public computer computer1(){        return new computer(笔记本电脑);    }    @conditionalonmissingbean(computer.class)    @bean(reservepc)    public computer computer2(){        return new computer(备用电脑);    }}

public class testapp {    annotationconfigapplicationcontext applicationcontext = new annotationconfigapplicationcontext(beanconfig.class);    @test    public void test1(){        map<string,computer> map = applicationcontext.getbeansoftype(computer.class);        system.out.println(map);    }}

修改beanconfig,如果注释掉第一个@bean,会实例化备用电脑,否则就不会实例化备用电脑
@conditionalonclass & @conditionalonmissingclass这个注解会判断类路径上是否有指定的类,一开始看到的时候比较困惑,类路径上如果没有指定的class,那编译也通过不了啊...这个主要用于集成相同功能的第三方组件时用,只要类路径上有该组件的类,就进行自动配置,比如spring boot web在自动配置视图组件时,是用velocity,还是thymeleaf,或是freemaker时,使用的就是这种方式。
例子是两套盔甲a(光明套装)和b(暗黑套装),如果a不在则配置b。
public interface fighter {    void fight();}public class fightera implements fighter {    @override    public void fight() {        system.out.println(使用光明套装);    }}public class fighterb implements fighter {    @override    public void fight() {        system.out.println(使用暗黑套装);    }}

van是武士,使用套装进行战斗
@data@allargsconstructor@noargsconstructorpublic class van {    private fighter fighter;    public void fight(){        fighter.fight();    }}

vanconfiga/b实例化武士
@configuration@conditionalonclass({fightera.class})public class vanconfiga {    @primary    @bean    public van vana(){        return new van(new fightera());    }}@configuration@conditionalonclass({fighterb.class})public class vanconfigb {    @bean    public van vanb(){        return new van(new fighterb());    }}

测试类,默认情况,如果套装ab都在类路径上,两套都会加载,a会设置为primary,如果在target class中将fighta.class删除,则只会加载套装b。
@springbootapplicationpublic class testapp implements commandlinerunner {    @autowired    private van van;    public static void main(string[] args) {        springapplication.run(testapp.class, args);    }    @override    public void run(string... args) throws exception {        //do something       van.fight();    }}

另外,尝试将两个vanconfiga/b合并,将注解conditionalonclass放到方法上,如果删除一个套装就会运行出错。
@conditionalonexpress依据表达式进行条件判断,这个作用和@conditionalonproperty大部分情况可以通用,表达式更灵活一点,因为可以使用spel。例子中会判断properties中test.enabled的值进行判断。beanconfig分别对布尔,字符串和数字三种类型进行判断。数字尝试了很多其他的方式均不行,比如直接使用==,貌似配置的属性都会当成字符串来处理。
@datapublic class testbean {    private string name;}

@configuration@conditionalonexpression(#{${test.enabled:true} })//@conditionalonexpression('zz'.equalsignorecase('${test.name2}'))//@conditionalonexpression(new integer('${test.account}')==1)public class beanconfig {    @bean    public testbean testbean(){        return new testbean(我是美猴王);    }}

@springbootapplicationpublic class testappcommand implements commandlinerunner {    @autowired    private testbean testbean;    public static void main(string[] args) {        springapplication.run(testappcommand.class, args);    }    @override    public void run(string... args) throws exception {        system.out.println(testbean.getname());    }}

@conditionalonproperty适合对单个property进行条件判断,而上面的@conditionalonexpress适合面对较为复杂的情况,比如多个property的关联比较。这个例子也给了三种基本类型的条件判断,不过貌似均当成字符串就可以...
@data@allargsconstructor@noargsconstructorpublic class testbean {    private string name;}

@configuration@conditionalonproperty(prefix = test, name=enabled, havingvalue = true,matchifmissing = false)//@conditionalonproperty(prefix = test, name=account, havingvalue = 1,matchifmissing = false)//@conditionalonproperty(prefix = test, name=name1, havingvalue = zz,matchifmissing = false)public class beanconfig {    @bean    public testbean testbean(){        return new testbean(我是美猴王);    }}

@springbootapplicationpublic class testappcommand implements commandlinerunner {    @autowired    private testbean testbean;    public static void main(string[] args) {        springapplication.run(testappcommand.class, args);    }    @override    public void run(string... args) throws exception {        system.out.println(testbean.getname());    }}

@conditionalonjava可以通过java的版本进行判断。
@datapublic class testbean {}



@configuration@conditionalonjava(javaversion.eight)public class beanconfig {    @bean    public testbean testbean(){        return new testbean();    }}

public class testapp {    annotationconfigapplicationcontext context = new annotationconfigapplicationcontext(beanconfig.class);    @test    public void test(){        map<string,testbean> map = context.getbeansoftype(testbean.class);        system.out.println(map);    }}

@conditionalonresource通过指定的资源文件是否存在进行条件判断,比如判断ehcache.properties来决定是否自动装配ehcache组件。
@datapublic class testbean {}



@configuration@conditionalonresource(resources = classpath:application.yml)public class beanconfig {    @bean    public testbean testbean(){        return new testbean();    }}

public class testapp {    annotationconfigapplicationcontext context = new annotationconfigapplicationcontext(beanconfig.class);    @test    public void test(){        map<string,testbean> map = context.getbeansoftype(testbean.class);        system.out.println(map);    }}

@conditionalonsinglecandidate这个还没有想到应用场景,条件通过的条件是:1 对应的bean容器中只有一个 2.对应的bean有多个,但是已经制定了primary。例子中,beanb装配的时候需要看beana的装配情况,所以beanbconfig要排在beanaconfig之后.可以修改beanaconfig,将@primary注解去掉,或者把三个@bean注解去掉,beanb就不会实例化了。
@data@allargsconstructor@noargsconstructorpublic class beana {    private string name;}

@configurationpublic class beanaconfig {    @bean    @primary    public beana bean1(){        return new beana(bean1);    }    @bean(autowirecandidate = false)    public beana bean2(){        return new beana(bean2);    }    //@bean(autowirecandidate = false)    public beana bean3(){        return new beana(bean3);    }}

@datapublic class beanb {}

@configuration@autoconfigureafter(beanaconfig.class)@conditionalonsinglecandidate(beana.class)public class beanbconfig {    @bean    public beanb targetbean(){        return new beanb();    }}

public class testapp {    annotationconfigapplicationcontext context = new annotationconfigapplicationcontext(beanaconfig.class, beanbconfig.class);    @test    public void test(){        map<string,beana> map = context.getbeansoftype(beana.class);        system.out.println(map);        map<string,beanb> map2 = context.getbeansoftype(beanb.class);        system.out.println(map2);    }}

@conditionalonnotwebapplication & @conditionalonwebapplication判断当前环境是否是web应用。
专栏文章详情
沈子平                                                                                                                                                                                        117                                                                                                                                                                                                                                                                                                            关注作者                                                
                                                   1 小时前发布                                                                                            
spring boot中的那些条件判断
                                                                                                                     java                                               19 次阅读                                                 ·                                                 读完需要 31 分钟
0
spring boot中的那些conditional
spring boot中为我们提供了丰富的conditional来让我们得以非常方便的在项目中向容器中添加bean。本文主要是对各个注解进行解释并辅以代码说明其用途。
所有conditionalonxxx的注解都可以放置在class或是method上,如果方式在class上,则会决定该class中所有的@bean注解方法是否执行。
@conditional下面其他的conditional注解均是语法糖,可以通过下面的方法自定义conditionalonxxx
conditional注解定义如下,接收实现condition接口的class数组。
public @interface conditional {    class<? extends condition>[] value();}

而condition接口只有一个matchs方法,返回是否匹配的结果。
public interface condition {    boolean matches(conditioncontext context, annotatedtypemetadata metadata);}

通过操作系统进行条件判断,从而进行bean配置。当window时,实例化bill的person对象,当linux时,实例化linus的person对象。
//linuxcondition,为方便起见,去掉判断代码,直接返回true了public class linuxcondition implements condition {    @override    public boolean matches(conditioncontext conditioncontext, annotatedtypemetadata annotatedtypemetadata) {        return true;    }}

//windowscondition,为方便起见,去掉判断代码,直接返回false了public class windowscondition implements condition {    @override    public boolean matches(conditioncontext conditioncontext, annotatedtypemetadata metadata) {        return false;    }}

@data@tostring@allargsconstructor@noargsconstructorpublic class person {    private string name;    private integer age;}

//配置类@configurationpublic class beanconfig {    @bean(name = bill)    @conditional({windowscondition.class})    public person person1(){        return new person(bill gates,62);    }    @bean(linus)    @conditional({linuxcondition.class})    public person person2(){        return new person(linus,48);    }}

public class apptest {    annotationconfigapplicationcontext applicationcontext = new annotationconfigapplicationcontext(beanconfig.class);    @test    public void test(){        string osname = applicationcontext.getenvironment().getproperty(os.name);        system.out.println(当前系统为: + osname);        map<string, person> map = applicationcontext.getbeansoftype(person.class);        system.out.println(map);    }}

输出的结果:
当前系统为:mac os x
{linus=person(name=linus, age=48)}@conditionalonbean & @conditionalonmissingbean这两个注解会对bean容器中的bean对象进行判断,使用的例子是配置的时候,如果发现如果没有computer实例,则实例化一个备用电脑。
@data@allargsconstructor@tostringpublic class computer {    private string name;}

@configurationpublic class beanconfig {    @bean(name = notebookpc)    public computer computer1(){        return new computer(笔记本电脑);    }    @conditionalonmissingbean(computer.class)    @bean(reservepc)    public computer computer2(){        return new computer(备用电脑);    }}

public class testapp {    annotationconfigapplicationcontext applicationcontext = new annotationconfigapplicationcontext(beanconfig.class);    @test    public void test1(){        map<string,computer> map = applicationcontext.getbeansoftype(computer.class);        system.out.println(map);    }}

修改beanconfig,如果注释掉第一个@bean,会实例化备用电脑,否则就不会实例化备用电脑
@conditionalonclass & @conditionalonmissingclass这个注解会判断类路径上是否有指定的类,一开始看到的时候比较困惑,类路径上如果没有指定的class,那编译也通过不了啊...这个主要用于集成相同功能的第三方组件时用,只要类路径上有该组件的类,就进行自动配置,比如spring boot web在自动配置视图组件时,是用velocity,还是thymeleaf,或是freemaker时,使用的就是这种方式。
例子是两套盔甲a(光明套装)和b(暗黑套装),如果a不在则配置b。
public interface fighter {    void fight();}public class fightera implements fighter {    @override    public void fight() {        system.out.println(使用光明套装);    }}public class fighterb implements fighter {    @override    public void fight() {        system.out.println(使用暗黑套装);    }}

van是武士,使用套装进行战斗
@data@allargsconstructor@noargsconstructorpublic class van {    private fighter fighter;    public void fight(){        fighter.fight();    }}

vanconfiga/b实例化武士
@configuration@conditionalonclass({fightera.class})public class vanconfiga {    @primary    @bean    public van vana(){        return new van(new fightera());    }}@configuration@conditionalonclass({fighterb.class})public class vanconfigb {    @bean    public van vanb(){        return new van(new fighterb());    }}

测试类,默认情况,如果套装ab都在类路径上,两套都会加载,a会设置为primary,如果在target class中将fighta.class删除,则只会加载套装b。
@springbootapplicationpublic class testapp implements commandlinerunner {    @autowired    private van van;    public static void main(string[] args) {        springapplication.run(testapp.class, args);    }    @override    public void run(string... args) throws exception {        //do something       van.fight();    }}

另外,尝试将两个vanconfiga/b合并,将注解conditionalonclass放到方法上,如果删除一个套装就会运行出错。
@conditionalonexpress依据表达式进行条件判断,这个作用和@conditionalonproperty大部分情况可以通用,表达式更灵活一点,因为可以使用spel。例子中会判断properties中test.enabled的值进行判断。beanconfig分别对布尔,字符串和数字三种类型进行判断。数字尝试了很多其他的方式均不行,比如直接使用==,貌似配置的属性都会当成字符串来处理。
@datapublic class testbean {    private string name;}

@configuration@conditionalonexpression(#{${test.enabled:true} })//@conditionalonexpression('zz'.equalsignorecase('${test.name2}'))//@conditionalonexpression(new integer('${test.account}')==1)public class beanconfig {    @bean    public testbean testbean(){        return new testbean(我是美猴王);    }}

@springbootapplicationpublic class testappcommand implements commandlinerunner {    @autowired    private testbean testbean;    public static void main(string[] args) {        springapplication.run(testappcommand.class, args);    }    @override    public void run(string... args) throws exception {        system.out.println(testbean.getname());    }}

@conditionalonproperty适合对单个property进行条件判断,而上面的@conditionalonexpress适合面对较为复杂的情况,比如多个property的关联比较。这个例子也给了三种基本类型的条件判断,不过貌似均当成字符串就可以...
@data@allargsconstructor@noargsconstructorpublic class testbean {    private string name;}

@configuration@conditionalonproperty(prefix = test, name=enabled, havingvalue = true,matchifmissing = false)//@conditionalonproperty(prefix = test, name=account, havingvalue = 1,matchifmissing = false)//@conditionalonproperty(prefix = test, name=name1, havingvalue = zz,matchifmissing = false)public class beanconfig {    @bean    public testbean testbean(){        return new testbean(我是美猴王);    }}

@springbootapplicationpublic class testappcommand implements commandlinerunner {    @autowired    private testbean testbean;    public static void main(string[] args) {        springapplication.run(testappcommand.class, args);    }    @override    public void run(string... args) throws exception {        system.out.println(testbean.getname());    }}

@conditionalonjava可以通过java的版本进行判断。
@datapublic class testbean {}



@configuration@conditionalonjava(javaversion.eight)public class beanconfig {    @bean    public testbean testbean(){        return new testbean();    }}

public class testapp {    annotationconfigapplicationcontext context = new annotationconfigapplicationcontext(beanconfig.class);    @test    public void test(){        map<string,testbean> map = context.getbeansoftype(testbean.class);        system.out.println(map);    }}

@conditionalonresource通过指定的资源文件是否存在进行条件判断,比如判断ehcache.properties来决定是否自动装配ehcache组件。
@datapublic class testbean {}



@configuration@conditionalonresource(resources = classpath:application.yml)public class beanconfig {    @bean    public testbean testbean(){        return new testbean();    }}

public class testapp {    annotationconfigapplicationcontext context = new annotationconfigapplicationcontext(beanconfig.class);    @test    public void test(){        map<string,testbean> map = context.getbeansoftype(testbean.class);        system.out.println(map);    }}

@conditionalonsinglecandidate这个还没有想到应用场景,条件通过的条件是:1 对应的bean容器中只有一个 2.对应的bean有多个,但是已经制定了primary。例子中,beanb装配的时候需要看beana的装配情况,所以beanbconfig要排在beanaconfig之后.可以修改beanaconfig,将@primary注解去掉,或者把三个@bean注解去掉,beanb就不会实例化了。
@data@allargsconstructor@noargsconstructorpublic class beana {    private string name;}

@configurationpublic class beanaconfig {    @bean    @primary    public beana bean1(){        return new beana(bean1);    }    @bean(autowirecandidate = false)    public beana bean2(){        return new beana(bean2);    }    //@bean(autowirecandidate = false)    public beana bean3(){        return new beana(bean3);    }}

@datapublic class beanb {}

@configuration@autoconfigureafter(beanaconfig.class)@conditionalonsinglecandidate(beana.class)public class beanbconfig {    @bean    public beanb targetbean(){        return new beanb();    }}

public class testapp {    annotationconfigapplicationcontext context = new annotationconfigapplicationcontext(beanaconfig.class, beanbconfig.class);    @test    public void test(){        map<string,beana> map = context.getbeansoftype(beana.class);        system.out.println(map);        map<string,beanb> map2 = context.getbeansoftype(beanb.class);        system.out.println(map2);    }}

@conditionalonnotwebapplication & @conditionalonwebapplication判断当前环境是否是web应用。
举报
赞  |                                  0 收藏  |  0
你可能感兴趣的
评论                                                    
默认排序                        时间排序
载入中...
显示更多评论
发布评论
以上就是spring boot中的条件判断的介绍(附代码)的详细内容。
其它类似信息

推荐信息