2009-07-23 6 views
38

Tôi đã một lớp Enummùa xuân - Làm thế nào để bạn thiết lập phím Enum trong một bản đồ với các chú thích

public enum MyEnum{ 
    ABC; 
} 

hơn lớp 'Mick' của tôi có tài sản này

private Map<MyEnum, OtherObj> myMap; 

Tôi đã vào mùa xuân này cấu hình xml.

<util:map id="myMap"> 
    <entry key="ABC" value-ref="myObj" /> 
</util:map> 

<bean id="mick" class="com.x.Mick"> 
    <property name="myMap" ref="myMap" /> 
</bean> 

và điều này là tốt.
Tôi muốn thay thế cấu hình xml này bằng chú thích mùa xuân.
Bạn có ý tưởng nào về cách tự động bản đồ không?

Vấn đề ở đây là nếu tôi chuyển từ xml config để chú thích @Autowired (trên thuộc tính myMap của lớp Mick) Mùa xuân đang ném ngoại lệ này

nested exception is org.springframework.beans.FatalBeanException: Key type [class com.MyEnum] of map [java.util.Map] must be assignable to [java.lang.String] 

mùa xuân không có nhiều khả năng nhận chuỗi ABC như một đối tượng MyEnum.ABC.
Bất kỳ ý tưởng nào?

Cảm ơn

+0

Nó không rõ ràng những gì bạn đang cố gắng để làm. Bạn đang nghĩ đến loại chú thích nào? – skaffman

+0

Tôi muốn sử dụng chú thích @Autowired nhưng nó không hoạt động. Tôi có phải chỉ định một cái gì đó khác để cho Spring biết rằng giá trị Key là một Enum thay vì một String? – mickthompson

Trả lời

44

này làm việc cho tôi ...

My bối cảnh ứng dụng Spring:

<util:map id="myMap"> 
    <entry key="#{T(com.acme.MyEnum).ELEM1}" value="value1" /> 
    <entry key="#{T(com.acme.MyEnum).ELEM2}" value="value2" /> 
</util:map> 

Lớp học của tôi nơi Map được tiêm:

public class MyClass { 

    private @Resource Map<MyEnum, String> myMap; 
} 

Những điều quan trọng cần lưu ý là trong bối cảnh mùa xuân tôi đã sử dụng Spel (Ngôn ngữ biểu hiện mùa xuân) chỉ có sẵn kể từ phiên bản 3.0. Và trong lớp học của tôi, tôi đã sử dụng @Resource, không phải @Inject (nó không làm việc cho tôi) cũng không phải @Autowired (Tôi đã không thử điều này).Sự khác biệt duy nhất mà tôi nhận thấy là giữa @Resource@Autowired, là trước đây tự động tiêm bằng tên bean trong khi sau đó nó được thực hiện theo loại bean.

Tận hưởng!

+9

Hãy nhớ sử dụng '$' thay vì '.' để tách một enum bên trong từ một lớp bên ngoài trong Spring EL. –

+6

Chỉ cần theo dõi rằng '@ Autowired' cũng sẽ tạo ra' Loại khóa [class com.foo.Bar $ BAZ] của bản đồ [java.util.Map] phải được gán cho [java.lang.String] ',' @ Tài nguyên' là người chiến thắng. +1 @Amir, '$' là một hình ảnh xác thực. – markdsievers

+0

Câu hỏi đã nói "Tôi muốn * thay thế * cấu hình xml này bằng chú thích mùa xuân". nhưng vẫn có cấu hình XML ở đây. Điều đó có nghĩa là bạn không thể làm điều này trong mùa xuân hoàn toàn bằng chú thích? – Jonik

1

nên là:

public class Mick { 

    private Map<MyEnum, OtherObj> myMap; 

    @Autowired 
    public void setMyMap(Map<MyEnum, OtherObj> myMap) { 
    this.myMap = myMap; 
    } 
} 

Có một cái nhìn tại http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-annotation-config

Cập nhật

Vấn đề là theo lược đồ util, bạn không thể chỉ định phím hoặc các loại giá trị. Tuy nhiên, bạn có thể thực hiện một MapFactoryBean của riêng bạn (chỉ kế thừa từ org.springframework.beans.factory.config.MapFactoryBean). Một ceveat - thông báo rằng định nghĩa chung (ngay cả suy nghĩ bị xóa trong thời gian chạy) không bị cản trở.

+0

Xin chào David, tôi biết về chú thích @Autowired. Ở đây vấn đề là nếu tôi tự động bản đồ Spring không thể nhận ra chuỗi ABC như một đối tượng MyEnum.ABC. Với cấu hình XML nó hoạt động tốt, với cấu hình chú thích nó ném ngoại lệ này ngoại lệ lồng nhau là org.springframework.beans.FatalBeanException: Loại khóa [class com.MyEnum] của bản đồ [java.util.Map] phải được gán cho [java. lang.String] – mickthompson

+0

Tôi đã cập nhật câu trả lời của mình. –

0

Phần tử <util:map> có loại khóa, resp. thuộc tính kiểu giá trị, đại diện cho lớp của các khóa, resp. giá trị. Nếu bạn chỉ định lớp đủ điều kiện của enum của bạn trong thuộc tính type-key, các khóa sau đó được phân tích cú pháp vào enum đó khi tạo bản đồ.

Mùa xuân xác minh trong quá trình tiêm rằng các loại khóa và giá trị của bản đồ được khai báo trong lớp có chứa tương thích gán bản đồ với các loại khóa và giá trị của hạt bản đồ. Đây thực sự là nơi bạn có ngoại lệ.

15

Điều này đã cho tôi phù hợp nhưng tôi đã có thể ghép nó lại với nhau bằng câu trả lời của David và một số liên kết khác (bên dưới).

  • không thay đổi tên của thuộc tính trong khai báo MapFactoryBean.
  • đảm bảo rằng thuộc tính loại khóa trỏ đến enum mà bạn muốn sử dụng làm khóa trong bản đồ.

Lớp

@Component 
public class MyClass { 

    private Map<MyEnum, ValueObjectInterface> valueMap; 

    @Autowired 
    public void setValueMap(final Map<MyEnum, ValueObjectInterface> valueMap) { 
     this.valueMap= valueMap; 
    } 


} 

Enum

public enum MyEnum{ 
    FOO ("FOO"), 
    BAR ("BAR"), 
    BAZ ("BAZ"); 
} 

XML Config file:

<bean id="valueMap" class="org.springframework.beans.factory.config.MapFactoryBean"> 
    <property name="targetMapClass"> 
     <value>java.util.HashMap</value> 
    </property> 
    <property name="sourceMap"> 
     <map key-type="com.company.packagepath.MyEnum"> 
      <entry key="FOO" value-ref="valueObject1" /> 
      <entry key="BAR" value-ref="valueObject2" /> 
      <entry key="BAZ" value-ref="valueObject3" /> 
     </map> 
    </property> 
</bean> 

<bean id="valueObject1" class="com.company.packagepath.ValueObject1" /> 
<bean id="valueObject2" class="com.company.packagepath.ValueObject2" /> 
<bean id="valueObject3" class="com.company.packagepath.ValueObject3" /> 

LIÊN KẾT

5

bối cảnh ứng dụng

<?xml version="1.0" encoding="UTF-8"?> 

<beans xmlns="http://www.springframework.org/schema/beans" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:util="http://www.springframework.org/schema/util" 
     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 
      http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd "> 

<bean id="myProvider" class="com.project.MapProvider"> 
    <property name="myMap" ref="myMap"/> 
</bean> 

<util:map id="myMap" key-type="com.project.MyEnum" value-type="com.project.ValueObject"> 
    <entry> 
     <key><value type="com.project.MyEnum">FOO</value></key> 
     <ref bean="objectValue1"/> 
    </entry> 
</util:map> 
</beans> 

lớp Java

package com.project; 

public class MapProvider { 

    private Map<MyEnum, ValueObject> myMap; 

    public void setMyMap(Map<MyEnum, ValueObject> myMap) { 
     this.myMap = myMap; 
    } 
} 
+0

Câu trả lời cần giải thích thêm một chút về những gì bạn liệt kê ở đây. – Markus

+0

Tôi đã tạo bản đồ với enum làm khóa và sử dụng nó cho đối số setter. Tôi nghĩ nó là hiển nhiên :) –