【Spring Boot】4.条件化Bean 根据配置文件加载对应Bean 秒速五厘米 2021-09-21 08:38 777阅读 0赞 > 根据配置文件只加载指定的Bean,条件化Bean 近期在工作中遇到实际问题:在不同的环境中,需要加载不同的工具类。这个就可以使用到Spring的条件化Bean。 话不多说,直接上代码。 例如,当前对于IService接口: public interface IService { void test(); } 有两个不同的实现类: public class AwsServiceImpl implements IService{ @Override public void test() { System.out.println("AwsServiceImpl test ... "); } } public class HttpServiceImpl implements IService{ @Override public void test() { System.out.println("HttpServiceImpl test ... "); } } 而在不同的环境中,需要调用不同的实现类。一种思路是在配置文件中声明环境,并将两个实现类存入一个`map<String, IService>`中,KEY为不同的环境,即在不同的环境中,可以调用特定的实现类,具体的代码如下: 首先在配置文件中声明环境: # 使用 aws,internal 标明外网环境与内网环境 env=aws 代码实现: @Service public class TestService { private final static String ENV_AWS = "aws"; private final static String ENV_INTERNAL = "internal"; private String env; private AwsServiceImpl awsService; private HttpServiceImpl httpService; private Map<String, IService> serviceMap; @Autowired public TestService(AwsServiceImpl awsService, HttpServiceImpl httpService, @Value("${env}") String env) { this.awsService = awsService; this.httpService = httpService; this.env = env; } @PostConstruct public void init() { // 初始化 Map<String, IService> serviceMap = new HashMap<>(4); serviceMap.put(ENV_AWS, awsService); serviceMap.put(ENV_INTERNAL, httpService); } public void test() { // 根据环境配置,调用不同的服务 serviceMap.get(env).test(); } } 该思路可以实现功能,但缺点在于多初始化了一个不会使用到的类,同时每次调用服务时,还需要获取特定的服务。因此,我们希望,能根据配置文件,只加载特定的Bean。这里就要使用到`ConditionalOnProperty`注解。 通过配置: @ConditionalOnProperty( name = "xx", havingValue = "yy" ) Spring会判断配置文件中的配置项xx,是否值为yy,如果值不相等,则不会生成该类,现在将上面的代码进行修改。 两个实现类: @Service @ConditionalOnProperty( name = "env", havingValue = "aws" ) public class AwsServiceImpl implements IService{ @PostConstruct public void init() { System.out.println("AwsServiceImpl init ... "); } @Override public void test() { System.out.println("AwsServiceImpl test ... "); } } @Service @ConditionalOnProperty( name = "env", havingValue = "internal" ) public class HttpServiceImpl implements IService{ @PostConstruct public void init() { System.out.println("HttpServiceImpl init ... "); } @Override public void test() { System.out.println("HttpServiceImpl test ... "); } } 此时配置文件配置: env=aws 启动项目,查看日志,可以发现与配置值对应的`AwsServiceImpl`进行了初始化: ![在这里插入图片描述][20200624224620543.png]而在其他类中,若要调用,也无需再采用Map的形式,可以直接注入对应类。虽然有两个接口的实现类,但是由于实际程序运行时,只有一个实现类会被初始化,因此下面的代码可以正确调用。 @Service public class MainService { private IService iService; @Autowired public MainService(IService iService) { this.iService = iService; } public void test() { iService.test(); } } Demo代码的Github链接: https://github.com/Parallelline1996/Daily-Learning/tree/master/SpringBoot/code-repository/SpringBoot-Conditional-Property [20200624224620543.png]: /images/20210920/6e0e910712da43a596d544c4878adf3c.png
还没有评论,来说两句吧...