我想创建一个包含属性文件值的bean。我做了这样的事情:
@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
,因为names
和ids
在尝试访问构造函数时未启动。
如果我制作了一些类似init()
的方法,并尝试使用它,则没有任何问题。
public init() throws Exception {
for (int i = 0; i < names.length; i++) {
navs.add(new Nav(names[i], ids[i]));
}
}
但是,我不想手动启动。我可以在构造函数中启动它吗?还是其他任何替代方案?
答案 0 :(得分:7)
在@PostConstruct
方法上使用init()
- 一旦对象在spring上下文中,它就会被spring调用,这意味着所有它都会被注入。
答案 1 :(得分:2)
考虑一下:对于spring向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]));
}
}
答案 2 :(得分: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();
}
}