Spring Java配置 - 如何为bean-references创建枚举映射

时间:2012-11-08 16:29:59

标签: java spring

使用基于Java的配置,我试图将枚举映射到bean引用的映射转换为纯java配置(目前在XML和工作中),但似乎无法在文档中找到任何内容;

目前,我的XML就像这样;

<util:map id="colourHanders" key-type="com.example.ColourEnum"
          value-type="com.example.ColourHandler">
    <entry key="white" value-ref="whiteColourHandler"/>
    <entry key="blue" value-ref="blueColourHandler"/>
    <entry key="red" value-ref="redColourHandler"/>
</util:map>

我确信它很简单,但是再一次找不到关于如何在Pure Java中表示这一点的任何内容(所以我没有任何XML配置文件)..

请注意; ColourHandler bean是使用@Component注释创建的,例如..

@Component
public class RedColourHandler implements ColourHander{
.....
}

并且colourHandlers的地图被引用为;

@Resource(name="colourHandlers")
    private Map<ColourHandlerEnum, ColourHandler> colourHandlers;

谢谢,

伊恩。

5 个答案:

答案 0 :(得分:15)

你可能想要这样的东西:

@Configuration
public class MyConfiguration {
    @Bean public Map<ColourEnum, ColourHandler> colourHandlers() {
        Map<ColourEnum, ColourHandler> map = new EnumMap<>();
        map.put(WHITE, whiteHandler());
        // etc
        return map;
    }

    @Bean public ColourHandler whiteHandler() {
        return new WhiteHandler();
    }
}

如果您需要将处理程序保留为@Component,则可以将它们自动装入配置类:

@Configuration
public class MyConfiguration {
    @Autowired private WhiteColourHandler whiteColourHandler;

    @Bean public Map<ColourEnum, ColourHandler> colourHandlers() {
        Map<ColourEnum, ColourHandler> map = new EnumMap<>();
        map.put(WHITE, whiteColourHandler);
        return map;
    }
}

答案 1 :(得分:1)

这实际上非常简单,但你需要知道如何:

 @Autowired private ColourHandler whiteColourHandler;
 ...

 public Map<ColourEnum, ColourHandler> getColourHander() {
     Map<ColourEnum, ColourHandler> result = ...;
     map.put( ColourEnum.white, whiteColourHandler );
     ...
     return map;
 }

诀窍是你可以将bean注入配置。

答案 2 :(得分:1)

与接受的答案类似,除了可以像往常一样在配置类中声明bean而不是自动装配组件,并将它们作为参数传递给Map bean方法:

@Configuration
public class MyConfiguration {
    @Bean public Map<ColourEnum, ColourHandler> colourHandlers(ColourHandler whiteHandler) {
        Map<ColourEnum, ColourHandler> map = new EnumMap<>();
        map.put(WHITE, whiteHandler);
        return map;
    }

    @Bean public ColourHandler whiteHandler() {
        return new WhiteHandler();
    }
}

另请注意,如果字段名称遵循与bean定义相同的命名约定,则将映射作为@Resource注入不需要注释的“name”参数。

即。这将没有name参数:

@Resource
private Map<ColourHandlerEnum, ColourHandler> colourHandlers;

但这需要它:

@Resource(name="colourHandlers")
private Map<ColourHandlerEnum, ColourHandler> handlers;

答案 3 :(得分:0)

由于每个ColorHandler都有一个唯一的类/ @Component,我只想让Spring弄清楚要使用什么(不需要@Autowire注入或任何其他创建方法):

@Configuration
public class MyConfiguration {
    @Bean public Map<ColourEnum, ColourHandler> colourHandlers(
            WhiteColourHandler whiteHandler, 
            BlueColourHandler blueHandler, 
            RedColourHandler redHandler) {
        Map<ColourEnum, ColourHandler> map = new EnumMap<>();
        map.put(WHITE, whiteHandler);
        map.put(BLUE, blueHandler);
        map.put(RED, redHandler);
        return map;
    }
}

答案 4 :(得分:0)

您可以让ColourHandler类本身定义其自己的类型,这样,在获取新类型时,您将不必继续更改配置类:

public interface ColourHander {
    ColourEnum getType();
}
@Component
public class RedColourHandler implements ColourHander{
    @Override
    public ColourEnum getType() {
        return ColourEnum.RED;
    }
}

在配置类中,您将获得所有ColourHandler并将其映射到它们的类型。

@Configuration
public class MyConfiguration {
    @Bean 
    public Map<ColourEnum, ColourHandler> colourHandlers(List<ColourHandler> colourHandlers) {
        return colourHandlers.stream().collect(toMap(ColourHandler::getType, x -> x));
    }
}

请注意,如果每种颜色有多个处理程序(我想这是预期的行为),您将得到一个IllegalStateException,您可以捕获并抛出自己的处理程序。