2011-08-31 66 views
1

我想創建一個bean,它具有屬性文件中的值。我做了這樣的事情:如何從構造函數訪問@Value註釋變量?

@Component 
public class MainNavs implements Iterable<Nav>{ 
    @Value("${newshome.navs.names}") 
    String[] names; 

    @Value("${newshome.navs.ids}") 
    String[] ids; 

    final private List<Nav> navs = new ArrayList<Nav>(); 

    public MainNavs() throws Exception {    
     for (int i = 0; i < names.length; i++) { 
      navs.add(new Nav(names[i], ids[i])); 
     } 
    } 

    public Iterator<Nav> iterator() { 
     Iterator<Nav> n = navs.iterator(); 
     return n; 
    } 

    public class Nav {  
     private String name; 
     private String id; 
     private String imageNumber; 

     public Nav(String name, String id, String imageNumber) { 
      this.name = name; 
      this.id = id; 
     } 

     //.... 
    } 
} 

但是,當我自動裝配這樣@Autowired MainNavs navs;,它使NullPointerException因爲namesids當它試圖訪問這些構造中並沒有啓動。

如果我提出了一些方法,如init()並試圖用它啓動,沒有任何問題。

public init() throws Exception {    
    for (int i = 0; i < names.length; i++) { 
     navs.add(new Nav(names[i], ids[i])); 
    } 
} 

但是,我不想手動啓動。我可以在構造函數中啓動它嗎?還是有其他的選擇?

+0

你應該指定使用什麼版本的spring,並將你的上下文xml(revelant部分)添加到你的問題中。這個http://forum.springsource.org/showthread.php?69602-Value-and-PropertyPlaceholderConfigurer可能也有幫助(差異順便說一句'#{...}'和'$ {...}') – 2011-08-31 05:41:17

回答

5

在您的init()方法上使用@PostConstruct - 只要對象位於spring上下文中,它就會被spring調用,這意味着如果它的依賴關係被注入,它就會全部被調用。

+0

感謝回答。保存了我的一天。 – minion

0

這樣的工作,你周圍可以使用工廠模式,是這樣的:

public class MainNavs implements Iterable<Nav>{ 

    // ... 

    public init() throws Exception {    
     for (int i = 0; i < names.length; i++) { 
      navs.add(new Nav(names[i], ids[i])); 
     } 
    } 

    public static MainNavs createInstance() throws Exception { 
    MainNavs result = new MainNavs(); 
    return result.init(); 
    } 
} 
2

想想看:春天注入東西到你的bean,它需要先創建,它是不是直到構造函數完成其工作。您可以懶惰地創建列表,也可以實現Spring接口InitializingBean。在你的情況下

public class MainNavs implements Iterable<Nav>, InitializingBean { 
... 
public void afterPropertiesSet() throws Exception {    
    for (int i = 0; i < names.length; i++) { 
     navs.add(new Nav(names[i], ids[i])); 
    } 
} 
+1

'InitializingBean'很好,但我建議@PostConstruct,因爲他似乎在使用註釋方法。 – Bozho

+0

是的,我同意,只是不記得註釋;-) –