2015-11-04 126 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