由ApplicationContextAware 引出spring动态注入的一种解决方案

最近公司项目有个代码设计需求:需要在RiskControlTaskController  中调用RiskControlService ,而RiskControlService 有多个实现类,如何在程序运行的过程中,动态的区调用接口的某个具体的实现类?

业务场景的参考代码如下:

接口实现类一:

@Transactional
@Service("hnRiskControlServiceImpl")
public class HnRiskControlServiceImpl implements RiskControlService 

接口实现类二:

@Transactional
@Service("zjRiskControlServiceImpl")
public class ZjRiskControlServiceImpl implements RiskControlService 

controller:

@RestController
@RequestMapping("/***/*****")
public class RiskControlTaskController  {

    private RiskControlService riskControlService;

    @RequestMapping("/****")
    public Response sendDataToTaskCenter(@RequestBody ParamDto paramDto) {

            tasks = riskControlService.verifyTasks(paramDto);
      
    }

可能细心的人会注意到  :  private RiskControlService riskControlService;   此处我并没有使用

@Autowired +@Qualifier,@Resource(name = "") 等等注解,当然使用@Conditional()注解可以解决唯一条件注入的问题。注意:不要有在程序运行的过程中为@Resource修改name属性值,以此来达到动态注入的想法,因为在默认情况下,spring注入的bean是单例的。

引出ApplicationContextAware

为什么类只要实现了ApplicationContextAware 就可以从spring中获取ioc容器

因为,有一个类,叫ApplicationContextAwareProcessor 实现了BeanPostProcessor(Bean的后置处理器) 重写了postProcessBeforeInitialization()方法----会在ioc容器中的bean初始化之前执行。在该方法内部,只要是ApplicationContextAware 的子类,就将bean强转为ApplicationContextAware 调用 setApplicationContext方法 ,设置applicationContext;

由此参照ApplicationContextAware 贴出我的解决方案:

首先:

public interface RiskControlTaskControllerAware extends Aware {

    void setRiskControlService(RiskControlService riskControlService) throws BeansException;
}

然后:

@Configuration
public class SendTaskServiceAware implements BeanPostProcessor {

    //1-浙江,2-湖南
    @Value("${deploymentLocation}")
    private Integer disposePlace;

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        invokeAwareInterfaces(bean);
        return bean;
    }

    private void invokeAwareInterfaces(Object bean) {
        if (bean instanceof RiskControlTaskControllerAware) {
            HnRiskControlServiceImpl hnRiskControlServiceImpl = (HnRiskControlServiceImpl) SpringBeanUtil.getBeanFromSpringByBeanName("hnRiskControlServiceImpl");
            ZjRiskControlServiceImpl zjRiskControlServiceImpl = (ZjRiskControlServiceImpl) SpringBeanUtil.getBeanFromSpringByBeanName("zjRiskControlServiceImpl");
            if (1 == disposePlace) {
                ((RiskControlTaskControllerAware) bean).setRiskControlService(zjRiskControlServiceImpl);
            } else if (2 == disposePlace) {
            }
            ((RiskControlTaskControllerAware) bean).setRiskControlService(hnRiskControlServiceImpl);
        }
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}

最后:

public class RiskControlTaskController implements RiskControlTaskControllerAware {



  
    private RiskControlService riskControlService;

    @Override
    public void setRiskControlService(RiskControlService riskControlService) throws BeansException {
        this.riskControlService = riskControlService;
    }

}

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值