2015-11-04 82 views
0

我有一個用戶細節類裏面,我放置地址類來存儲每個用戶細節類的多地址。我正在使用Spring 4.0。下面給出的代碼:在春天用豆列表

的UserDetails類:

@Component("userDetails") 

public class UserDetails { 

    @Resource(name="address") 
    @Autowired 
    private List<Address> address; 
    public List<Address> getAddress() { 
     return address; 
    } 
    @Autowired 
    public void setAddress(List<Address> address) { 
     this.address = address; 
    } 
} 

地址類:

@Component("address") 

public class Address { 

    private String area; 

    public String getArea() { 
     return area; 
    } 
    public void setArea(String area) { 
     this.area = area; 
    } 
} 

在這個例子中,Address.area值需要在運行時通過,然後我需要創建地址類的對象。然後它需要添加UserDetails類中的List地址變量。同樣,我需要在arrayList中添加n個數字對象,然後我需要爲UserDetails類創建一個對象。

我嘗試下面的代碼:

public class AppMain { 

    public static void main(String args[]){ 
     AbstractApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); 

     Address address = (Address)context.getBean("address"); 
     //setting first value: 
     address.setArea("XXX"); 

     Address address1 = (Address)context.getBean("address"); 
     //setting second value 
     address1.setArea("YYY"); 

     UserDetails userDetails = (UserDetails)context.getBean("userDetails"); 
     System.out.println("User Size: "+application.getAddress().size()); 
     System.out.println("User Details : "+application.getAddress().get(0).getArea()); 
     System.out.println("User Details : "+application.getAddress().get(1).getArea()); // getting ArrayIndexOutOfBoundException in this line 
    } 
} 

部分輸出: 用戶大小:1 用戶詳情:YYY

預期輸出: 用戶大小:2 用戶詳情:XXX 用戶詳情:YYY

您能否幫忙解決這個問題。

回答

0

注意,你是兩次得到同一個bean,所以這是不可能的,你得到兩次注射的是UserDetails列表:

Address address = (Address)context.getBean("address"); 
... 
Address address1 = (Address)context.getBean("address"); 

像這樣的東西應該工作:

@Configuration 
public class AppConfig{ 

    @Bean 
    public UserDetails userDetails(){ 
     return new UserDetails(); 
    } 

    @Bean 
    public Address addressXXX(){ 
     return new Address(); 
    } 

    @Bean 
    public Address addressYYY(){ 
     return new Address(); 
    } 

} 

那麼你的代碼:

Address address = (Address)context.getBean("addressXXX"); 
//setting first value: 
address.setArea("XXX"); 

Address address1 = (Address)context.getBean("addressYYY"); 
//setting second value 
address1.setArea("YYY"); 

UserDetails userDetails = (UserDetails)context.getBean("userDetails"); 
System.out.println("User Size: "+application.getAddress().size()); 
System.out.println("User Details : "+application.getAddress().get(0).getArea()); //--->XXX 
System.out.println("User Details : "+application.getAddress().get(1).getArea()); //--->YYY 
2

我不完全清楚你爲什麼要創建wha t似乎是使用Spring的域對象,但它看起來就是你在代碼中所做的。

Spring的概念爲Scope,它控制從ApplicationContext檢索bean時發生的情況。默認Scope單身人士這意味着您只能在ApplicationContext內獲得一個bean實例。這意味着您的電話context.getBean("address")總是返回相同的對象。

至於使用@Component註釋執行的接線;這在掃描類路徑時發生(通常在應用程序啓動時)。此時,Spring實例化每個類的單個實例,標記爲@Component,即一個Address和一個UserDetails。 Spring在設置address字段之前已足夠聰明,可以將單個Address添加到List,但僅此而已。然後

你的代碼檢索該從ApplicationContext設置在同一對象上區域兩次對象,因此爲什麼調試報表打印爲他們做的。

這解釋了你的代碼正在發生什麼,但留下了如何解決它的問題沒有答案。

正如我所說,我不明白爲什麼你會用Spring來構建看似是一個領域模型的東西。根據每個類的實例,域模型通常不會提前知道,因此Spring不是用於創建此類模型的適當工具(Spring通常用於將應用程序本身連接在一起)。

,需要修改域類的構造是這樣的:

public Address 
{ 
    private String area; 

    public Address(String area) 
    { 
    this.area = area; 
    } 

    ... 
} 

public UserDetails 
{ 
    private List<Address> addresses; 

    public UserDetails(Address... addresses) 
    { 
    this.addresses = Arrays.asList(addresses); 
    } 

    ... 
} 

然後主要方法可以重新寫成:

public static void main(String[] args) 
{ 
    UserDetails userDetails = new UserDetails(
    new Address("XXX"),   
    new Address("YYY"),   
    ); 

    System.out.println("User Size: " + application.getAddress().size()); 
    System.out.println("User Details: " + application.getAddress().get(0).getArea()); 
    System.out.println("User Details: " + application.getAddress().get(1).getArea()); 
} 
+0

在運行時只有我來知道有多少地址塊將要創建。 – Praveen