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() {
       ....
    }

谢谢大家!