Spring Boot:如何访问Java类@Autowired中的存储库不起作用

时间:2018-07-05 21:02:41

标签: spring spring-boot spring-data-jpa

Spring Boot:如何访问Java类@Autowired中的存储库不起作用

请使用示例代码来说明您的解决方案,因为我是Spring Boot的新手。

存储库

import java.util.List;
import org.springframework.data.repository.CrudRepository;

public interface StoreRepository extends CrudRepository<Store, Integer> {

    List<Store> findAll();
}

实体店

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class Store {

    @Id
    private Integer sid;
    private String sname;


    public Store() {

    }

    public Store(Integer sid, String sname) {
        super();
        this.sid = sid;
        this.sname = sname;

    }

///GETTER and Setters   here...

}

**商店服务**

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


@Service
public class StoreService {

    @Autowired
    private StoreRepository storeRepository;

    public StoreService() {

    }

    public List<Stores> getAllStores(){
        return (List<Stores>) storeRepository.findAll(); /* This works good. Through controller I can retrieve all data*/

    }

}

简单的Java类

@Component
public class StoreWorker {

    @Autowired
    private StoreRepository storeRepository;

    public StoreWorker() {

        System.out.println(storeRepository.findAll()); /* Error */

    }

错误:

Exception in thread "StoreWorker : restartedMain" java.lang.reflect.InvocationTargetException
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [io.store.workers.StoreWorker]: Constructor threw exception; nested exception is java.lang.NullPointerException
Caused by: java.lang.NullPointerException

请使用示例代码来说明您的解决方案,因为我是Spring Boot的新手。

3 个答案:

答案 0 :(得分:0)

您必须以这种方式更改代码:

如果要在类的构造函数中使用自动装配的Bean,请使用构造函数注入。这也是最推荐的注射方式。

@Component
public class StoreWorker {

    private final StoreRepository storeRepository;

    public StoreWorker(StoreRepository storeRepository) {
        this.storeRepository = storeRepository;
        System.out.println(storeRepository.findAll());
    }
}

因此,当StoreWorker实例化时,自动装配的bean storeRepository被注入。由于发生了这种情况,因此您可以使用storeRepository bean。

答案 1 :(得分:0)

您不应在构造函数中添加任何逻辑。构造方法只是用来初始化您的实例。 通过单独的方法调用storeRepository

@Component
public class StoreWorker {
    @Autowired
    private StoreRepository storeRepository;

    public void findAll() {
        System.out.println(storeRepository.findAll()); 
    }
}

当Spring调用您的构造函数时,上下文尚未完全初始化,并且由于您未使用构造函数注入,因此storeRepository尚未注入。

构造器注入是Spring团队推荐的注入方式。从Spring 4.3开始,您甚至不需要在构造函数上添加@Autowired批注。

@Component
public class StoreWorker {

    private StoreRepository storeRepository;

    //@Autowired not needed since v4.3
    public StoreWorker(StoreRepository storeRepository) {
        this.storeRepository = storeRepository;
    }

    ...
}

如果要依赖其他外部Bean进一步初始化Bean,请使用带有@PostConstruct注释的单独方法进行。

@Component
public class StoreWorker {

    private StoreRepository storeRepository;
    private List<Store> stores;

    public StoreWorker(StoreRepository storeRepository) {
        this.storeRepository = storeRepository;
    }

    @PostConstruct
    public void initializeMyBean() {
        stores = storeRepository.findAll(); 
    }
}

答案 2 :(得分:-1)

您应该在构造函数级别使用@Autowire,以便在构造函数内部使用Autowire变量。

@Component
public class StoreWorker {


@Autowired
public StoreWorker(StoreRepository storeRepository) {

    System.out.println(storeRepository.findAll()); 

}

(或)使用PostConstruct

Autowiring在构造对象之后发生。因此,只有在构造函数完成后才能设置它们。

如果您需要运行一些初始化代码,则应该能够将构造函数中的代码放入方法中,并使用@PostConstruct对该方法进行注释。