SpringBoot使用@Autowired将实现类注入到List或者Map集合中

前言

最近看到RuoYi-Vue-Plus翻译功能 Translation的翻译模块配置类TranslationConfig,其中有一个注入TranslationInterface翻译接口实现类的写法让我感到很新颖,但这种写法在Spring 3.0版本以后就已经支持注入ListMap,平时都没有注意到这一块,故此记录一下这种写法。

之前的做法

之前一般定义策略模式+工厂模式结合Spring上下文的Aware回调拿到指定类型Bean对象,这里列举一些能拿到指定类型Bean的方法:

  • 方法一:在初始化时保存ApplicationContext对象
  • 方法二:通过Spring提供的utils类获取ApplicationContext对象
  • 方法三:继承自抽象类ApplicationObjectSupport
  • 方法四:继承自抽象类WebApplicationObjectSupport
  • 方法五:实现接口ApplicationContextAware
  • 方法六:通过Spring提供的ContextLoader

翻译模块配置类

TranslationConfig这里是翻译配置初始化的地方

package com.ruoyi.framework.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.annotation.TranslationType;
import com.ruoyi.common.translation.TranslationInterface;
import com.ruoyi.common.translation.handler.TranslationBeanSerializerModifier;
import com.ruoyi.common.translation.handler.TranslationHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 翻译模块配置类
 *
 * @author Lion Li
 */
@Slf4j
@Configuration
public class TranslationConfig {
    
    

    @Autowired
    private List<TranslationInterface<?>> list;

    @Autowired
    private ObjectMapper objectMapper;

    @PostConstruct
    public void init() {
    
    
        Map<String, TranslationInterface<?>> map = new HashMap<>(list.size());
        for (TranslationInterface<?> trans : list) {
    
    
            if (trans.getClass().isAnnotationPresent(TranslationType.class)) {
    
    
                TranslationType annotation = trans.getClass().getAnnotation(TranslationType.class);
                map.put(annotation.type(), trans);
            } else {
    
    
                log.warn(trans.getClass().getName() + " 翻译实现类未标注 TranslationType 注解!");
            }
        }
        TranslationHandler.TRANSLATION_MAPPER.putAll(map);
        // 设置 Bean 序列化修改器
        objectMapper.setSerializerFactory(
            objectMapper.getSerializerFactory()
                .withSerializerModifier(new TranslationBeanSerializerModifier()));
    }

}

可以看到在这个配置类中注入了一个List集合,其类型为TranslationInterface翻译接口

我们来看一下它的实现类

这些实现类定义在common模块的translation包下,分别是部门字典OSS用户名的翻译实现

Spring会扫描TranslationInterface翻译接口实现类注入到List

我们来Debug看一下效果,可以看到TranslationInterface翻译接口的实现类确实全部已经注入进来了

由于@Autowired注解还可以注入BeanMap中,这里我们手动加上Map集合,Debug断点调试一下:

猜你喜欢

转载自blog.csdn.net/qq_31762741/article/details/132098537