Java Spring - 为什么自动装配的存储库在服务构造函数中为空?
Java Spring - Why are autowired Repositories null in Service constructors?
我正在测试一些东西并遇到了这种奇怪的行为。
我想做什么
假设我想使用本地文件、请求或其他任何方式将一些值预加载到存储库中。
通常我会把它们放在这样的构造函数中:
@Service
public class PointOfInterestService {
@Autowired
private PointOfInterestRepository pointOfInterestRepository;
public PointOfInterestService() {
try {
String jsonStr = Helper.isToString(new FileInputStream(new File("test.json")));
JSONObject json = new JSONObject(jsonStr);
JSONArray entries = json.getJSONArray("features");
for (Object element : entries) {
try {
//new PointOfInterest(...)
//read file and do stuff
//...
//finally, let's save the object
this.registerPointOfInterest(pointOfInterest);
}
} catch (Exception e) {
if (!(e instanceof JSONException)) {
e.printStackTrace();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void registerPointOfInterest(PointOfInterest pointOfInterest) {
pointOfInterestRepository.save(pointOfInterest);
}
}
当构造函数运行时,每当抛出 registerPointOfInterest
时都会弹出 NullPointerException
。
使用调试器我意识到由于某种原因存储库为空(因此抛出异常。
这是存储库 class,非常简单:
package com.example.demo.PointOfInterest;
import org.springframework.data.jpa.repository.JpaRepository;
public interface PointOfInterestRepository extends JpaRepository<PointOfInterest, String> {
}
是否有任何简单的变通方法可以在构造函数中读取上述文件?谢谢!
如果您有构造函数(因此服务本身不是单例),Spring 不会自动装配存储库。您应该用其他东西更改构造函数。
你可以试试这个:
@Service
public class PointOfInterestService {
private PointOfInterestRepository pointOfInterestRepository;
public PointOfInterestService(
@Autowired PointOfInterestRepository pointOfInterestRepository
) {
this.pointOfInterestRepository = pointOfInterestRepository;
}
您也可以删除构造函数中的@Autowired,因为spring 自动知道必须执行 DI。
@Service
public class PointOfInterestService {
private PointOfInterestRepository pointOfInterestRepository;
public PointOfInterestService(
PointOfInterestRepository pointOfInterestRepository
) {
this.pointOfInterestRepository = pointOfInterestRepository;
}
对于任何感兴趣的人,我实际上设法通过删除构造函数并在私有方法上使用 @PostConstruct
注释来解决这个问题,如下所示:
@PostConstruct
private void readGeoJson() {
....
}
谢谢大家!
我正在测试一些东西并遇到了这种奇怪的行为。
我想做什么
假设我想使用本地文件、请求或其他任何方式将一些值预加载到存储库中。
通常我会把它们放在这样的构造函数中:
@Service
public class PointOfInterestService {
@Autowired
private PointOfInterestRepository pointOfInterestRepository;
public PointOfInterestService() {
try {
String jsonStr = Helper.isToString(new FileInputStream(new File("test.json")));
JSONObject json = new JSONObject(jsonStr);
JSONArray entries = json.getJSONArray("features");
for (Object element : entries) {
try {
//new PointOfInterest(...)
//read file and do stuff
//...
//finally, let's save the object
this.registerPointOfInterest(pointOfInterest);
}
} catch (Exception e) {
if (!(e instanceof JSONException)) {
e.printStackTrace();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void registerPointOfInterest(PointOfInterest pointOfInterest) {
pointOfInterestRepository.save(pointOfInterest);
}
}
当构造函数运行时,每当抛出 registerPointOfInterest
时都会弹出 NullPointerException
。
使用调试器我意识到由于某种原因存储库为空(因此抛出异常。
这是存储库 class,非常简单:
package com.example.demo.PointOfInterest;
import org.springframework.data.jpa.repository.JpaRepository;
public interface PointOfInterestRepository extends JpaRepository<PointOfInterest, String> {
}
是否有任何简单的变通方法可以在构造函数中读取上述文件?谢谢!
如果您有构造函数(因此服务本身不是单例),Spring 不会自动装配存储库。您应该用其他东西更改构造函数。
你可以试试这个:
@Service
public class PointOfInterestService {
private PointOfInterestRepository pointOfInterestRepository;
public PointOfInterestService(
@Autowired PointOfInterestRepository pointOfInterestRepository
) {
this.pointOfInterestRepository = pointOfInterestRepository;
}
您也可以删除构造函数中的@Autowired,因为spring 自动知道必须执行 DI。
@Service
public class PointOfInterestService {
private PointOfInterestRepository pointOfInterestRepository;
public PointOfInterestService(
PointOfInterestRepository pointOfInterestRepository
) {
this.pointOfInterestRepository = pointOfInterestRepository;
}
对于任何感兴趣的人,我实际上设法通过删除构造函数并在私有方法上使用 @PostConstruct
注释来解决这个问题,如下所示:
@PostConstruct
private void readGeoJson() {
....
}
谢谢大家!