I want to make a bean which has values from properties file. I made something like this:
@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;
}
//....
}
}
But when I autowire like this @Autowired MainNavs 开发者_开发百科navs;
, it makes NullPointerException
because the names
and ids
were not initiated when it try to access those in constructor.
If I made some method like init()
and tried to initiate with it, there wasn't any problem.
public init() throws Exception {
for (int i = 0; i < names.length; i++) {
navs.add(new Nav(names[i], ids[i]));
}
}
However, I don't want initiate manually. Can I initiate it in constructor? Or any other alternatives?
Use @PostConstruct
on your init()
method - it will be called by spring as soon as the object is inside the spring context, which means all if its dependencies will be injected.
Think about it: for spring to inject something into your bean, it needs to be created first, and it isn't created until the constructor has finished its job. You can either create the list lazily, or you can implement the spring interface InitializingBean. In your case
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]));
}
}
As a work around you could use a factory pattern, something like:
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();
}
}
精彩评论