Spring的注入方式--構造方法--解決需要在構造方法裡面去初始化全域性變數
阿新 • • 發佈:2019-02-17
構造方法注入
public class UserService implements IUserService {
private IUserDao userDao;
public UserService(IUserDao userDao) {
this.userDao = userDao;
}
}
先看一段程式碼,下面的程式碼能執行成功嗎?
@Autowired private User user; private String school; public UserAccountServiceImpl(){ this.school = user.getSchool(); }
答案是不能。
因為Java類會先執行構造方法,然後再給註解了@Autowired 的user注入值,所以在執行構造方法的時候,就會報錯。
報錯資訊可能會像下面:
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name '...' defined in file [....class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [...]: Constructor threw exception; nested exception is java.lang.NullPointerException
報錯資訊說:建立Bean時出錯,出錯原因是例項化bean失敗,因為bean時構造方法出錯,在構造方法裡丟擲了空指標異常。
解決辦法是,使用構造器注入,如下:
private User user;
private String school;
@Autowired
public UserAccountServiceImpl(User user){
this.user = user;
this.school = user.getSchool();
}
可以看出,使用構造器注入的方法,可以明確成員變數的載入順序。
PS:Java變數的初始化順序為:靜態變數或靜態語句塊–>例項變數或初始化語句塊–>構造方法–>@Autowired
通過這種方法你可以實現呼叫某個Service的方法來初始化一些全域性引數,或者做快取預載入等。
還有另外一種方法也可以實現,那就是
@Component
@Order(10)
public class Init implements ApplicationRunner {
public void init() {
// do something
}
}
這種方式是在APP啟動之後去初始化,也可以實現初始化全域性引數