我们的应用可能部署在多个环境,有些依赖是环境隔离的,我们可能需要对部分Bean对象的创建是基于一些条件判断来生成。

Spring Bean有条件创建的机制,比如ConditionalOnProperty可以基于应用配置项来决定是否生成Bean对象。

比如:

1、application.properties

// 是否云单元
cloudUnit = true

2、ImManager.java

package net.suninf.api.facade;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class ImService {

    public void doSomeThing() {
        log.info("ImService doSomeThing");
    }
}

3、BeanConfig.java

package net.suninf.api.config;

import lombok.extern.slf4j.Slf4j;
import net.suninf.api.facade.ImService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Slf4j
@Configuration
public class BeanConfig {

    @Value("${cloudUnit}")
    private String cloudUnit;

    /**
     * 是否是上云单元
     * @return
     */
    public boolean isCloudUnit() {
        return "true".equals(cloudUnit);
    }

    /**
     * 基于配置是否生效
     * @return
     */
    @Bean
    @ConditionalOnProperty(name = "cloudUnit", havingValue = "true")
    public ImService imManager() {
        log.info("imManager");
        return new ImService();
    }
}

4、ImManagerFacade.java

package net.suninf.api.facade;

import lombok.extern.log4j.Log4j;
import net.suninf.api.config.BeanConfig;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

@Log4j
@Component
public class ImServiceFacade implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    private ImService imManager;

    @Resource
    private BeanConfig beanConfig;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @PostConstruct
    public void init() {
        boolean success = false;

        try {
            Object obj = this.applicationContext.getBean(ImService.class);
            if (obj != null) {
                // 动态初始化
                imManager = (ImService)obj;
                log.info("imManager init success");

                success = true;
            }
        } catch (Throwable e) {
        }

        if (!success) {
            log.info("imManager init fail");
        } else {
            doSomeThing();
        }
    }

    public void doSomeThing() {
        if (beanConfig.isCloudUnit()) {
            imManager.doSomeThing();
        }
    }
}

参考