https://blog.csdn.net/lucyTheSlayer/article/details/80430912

Spring的新引入的注解

 @ConditionalOnClass
是Springboot实现自动配置的重要支撑之一。其用途是判断当前classpath下是否存在指定类,若是则将当前的配置装载入spring容器。举例来说,如果在maven中引入了velocity,那么视图就使用velocity,若引入的是freemarker,则使用freemarker.

但是眼见为虚,手敲为实,所以自己决定来验证下其使用。

场景设在新日暮里,主角是van,是一个喜爱摔跤的格斗爱好者,他将向新日暮里的其他选手发起友谊比赛。这里,有两位新日暮里的强者,一位是新日暮里王,billy;另一位来自自由的大美利坚,香蕉君banana。van急于找人摔跤,因此只要有人在,他就发起挑战。

用intellj新建个springboot工程,目录如下:

入口类:
package com.ff.fun;
import com.ff.fun.player.Van;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
 
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
 
@SpringBootApplication
public class SbfunApplication implements CommandLineRunner{
 
    @Autowired
    private Van van;
 
    public static void main(String[] args) {
        SpringApplication.run(SbfunApplication.class, args);
    }
 
    @Override
    public void run(String... args) throws Exception {
        //do something
        van.fight();
    }
}
没什么好多说的,我们的主角Van开始了格斗。

主角Van:
package com.ff.fun.player;
 
import com.ff.fun.fighter.Fighter;
 
public class Van {
 
    private Fighter fighter;
 
    public Van(Fighter fighter) {
        this.fighter = fighter;
    }
 
    public void fight(){
        System.out.println("van:boy next door,do you like 玩游戏");
        fighter.fight();
    }
}
新日暮里格斗家们:
package com.ff.fun.fighter;
 
public interface Fighter {
 
    void fight();
}
package com.ff.fun.fighter;
 
public class Banana implements Fighter {
    @Override
    public void fight() {
        System.out.println("banana:自由的气息,蕉迟但到");
    }
}
package com.ff.fun.fighter;
 
public class Billy implements Fighter{
 
    @Override
    public void fight(){
        System.out.println("billy:吾乃新日暮里的王,三界哲学的主宰。");
    }
}

Config:
package com.ff.fun.config;
 
import com.ff.fun.player.Van;
import com.ff.fun.fighter.Billy;
import com.ff.fun.fighter.Fighter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
@Configuration
@ConditionalOnClass({Billy.class})
public class VanConfig {
 
    @Bean
    public Fighter billy(){
        return new Billy();
    }
 
    @Bean
    public Van van(){
        return new Van(billy());
    }
}
package com.ff.fun.config;
 
import com.ff.fun.player.Van;
import com.ff.fun.fighter.Banana;
import com.ff.fun.fighter.Fighter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
@Configuration
@ConditionalOnClass({Banana.class})
public class Van2Config {
    @Bean
    public Fighter banana(){
        return new Banana();
    }
 
    @Bean
    public Van van(){
        return new Van(banana());
    }
}
这就是重点了,这两个带条件的配置类,一个是当Billy在的时候启用,一个是在当Banana在的时候启用

试验环节:
编译后,在target中,可见


这两个类,这时候如果直接执行程序,会输出:
van:boy next door,do you like 玩游戏
billy:吾乃新日暮里的王,三界哲学的主宰。
说明,当候选类都在的情况下,spring会挑其中之一(至于如何选择的得另行研究);

这时候,删掉Billy.class,让吾王下线,新日暮里就只剩下Banana一个哲学战士了,此时,再次运行,输出为:

van:boy next door,do you like 玩游戏
banana:自由的气息,蕉迟但到
可以看到,billy的配置没有加载,van的对手是banana,@ConditionalOnClass这个注解起到了选择Config的作用。

此时,如果将香蕉君也删掉,新日暮里空无一人(⊙︿⊙),此时运行结果为:

***************************
APPLICATION FAILED TO START
***************************

Description:

Field van in com.ff.fun.SbfunApplication required a bean of type 'com.ff.fun.player.Van' that could not be found.
    - Bean method 'van' not loaded because @ConditionalOnClass did not find required class 'com.ff.fun.fighter.Banana'
    - Bean method 'van' not loaded because @ConditionalOnClass did not find required class 'com.ff.fun.fighter.Billy'


Action:

Consider revisiting the conditions above or defining a bean of type 'com.ff.fun.player.Van' in your configuration.
意料之中,报错了,一切符合预期。
--------------------- 
作者:放开那禽兽冲我来 
来源:CSDN 
原文:https://blog.csdn.net/lucyTheSlayer/article/details/80430912 
版权声明:本文为博主原创文章,转载请附上博文链接!

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐